From 30fdf1140b8d1ce93f3821d986fa165552023440 Mon Sep 17 00:00:00 2001 From: lgao4 Date: Fri, 17 Jul 2009 09:10:31 +0000 Subject: Check In tool source code based on Build tool project revision r1655. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8964 6f19259b-4bc3-4df7-8a09-765794883524 --- BaseTools/Source/Python/AutoGen/AutoGen.py | 1919 ++ BaseTools/Source/Python/AutoGen/BuildEngine.py | 622 + BaseTools/Source/Python/AutoGen/GenC.py | 1931 ++ BaseTools/Source/Python/AutoGen/GenDepex.py | 441 + BaseTools/Source/Python/AutoGen/GenMake.py | 1389 ++ BaseTools/Source/Python/AutoGen/StrGather.py | 532 + BaseTools/Source/Python/AutoGen/UniClassObject.py | 530 + BaseTools/Source/Python/AutoGen/__init__.py | 10 + BaseTools/Source/Python/Common/BuildToolError.py | 152 + BaseTools/Source/Python/Common/DataType.py | 401 + BaseTools/Source/Python/Common/Database.py | 120 + BaseTools/Source/Python/Common/DecClassObject.py | 563 + .../Source/Python/Common/DecClassObjectLight.py | 580 + BaseTools/Source/Python/Common/Dictionary.py | 75 + BaseTools/Source/Python/Common/DscClassObject.py | 1434 ++ BaseTools/Source/Python/Common/EdkIIWorkspace.py | 318 + .../Source/Python/Common/EdkIIWorkspaceBuild.py | 1669 ++ BaseTools/Source/Python/Common/EdkLogger.py | 269 + BaseTools/Source/Python/Common/FdfClassObject.py | 116 + BaseTools/Source/Python/Common/FdfParserLite.py | 3603 ++++ BaseTools/Source/Python/Common/GlobalData.py | 37 + BaseTools/Source/Python/Common/Identification.py | 58 + BaseTools/Source/Python/Common/InfClassObject.py | 1116 ++ .../Source/Python/Common/InfClassObjectLight.py | 876 + .../Source/Python/Common/MigrationUtilities.py | 567 + BaseTools/Source/Python/Common/Misc.py | 1327 ++ BaseTools/Source/Python/Common/Parsing.py | 935 + BaseTools/Source/Python/Common/PyUtility.pyd | Bin 0 -> 4608 bytes BaseTools/Source/Python/Common/String.py | 703 + .../Source/Python/Common/TargetTxtClassObject.py | 174 + .../Source/Python/Common/ToolDefClassObject.py | 217 + BaseTools/Source/Python/Common/XmlParser.py | 1754 ++ BaseTools/Source/Python/Common/XmlRoutines.py | 228 + BaseTools/Source/Python/Common/__init__.py | 0 .../Source/Python/CommonDataClass/CommonClass.py | 473 + .../Source/Python/CommonDataClass/DataClass.py | 351 + .../CommonDataClass/DistributionPackageClass.py | 159 + .../Source/Python/CommonDataClass/FdfClass.py | 402 + .../Source/Python/CommonDataClass/ModuleClass.py | 486 + .../Source/Python/CommonDataClass/PackageClass.py | 127 + .../Source/Python/CommonDataClass/PlatformClass.py | 432 + .../Source/Python/CommonDataClass/__init__.py | 0 BaseTools/Source/Python/Ecc/C.g | 626 + BaseTools/Source/Python/Ecc/CLexer.py | 4887 +++++ BaseTools/Source/Python/Ecc/CParser.py | 18825 +++++++++++++++++++ BaseTools/Source/Python/Ecc/Check.py | 865 + BaseTools/Source/Python/Ecc/CodeFragment.py | 165 + .../Source/Python/Ecc/CodeFragmentCollector.py | 624 + BaseTools/Source/Python/Ecc/Configuration.py | 264 + BaseTools/Source/Python/Ecc/Database.py | 344 + BaseTools/Source/Python/Ecc/Ecc.py | 329 + BaseTools/Source/Python/Ecc/EccGlobalData.py | 24 + BaseTools/Source/Python/Ecc/EccToolError.py | 179 + BaseTools/Source/Python/Ecc/Exception.py | 87 + BaseTools/Source/Python/Ecc/FileProfile.py | 57 + BaseTools/Source/Python/Ecc/MetaDataParser.py | 65 + BaseTools/Source/Python/Ecc/ParserWarning.py | 17 + BaseTools/Source/Python/Ecc/__init__.py | 0 BaseTools/Source/Python/Ecc/c.py | 2503 +++ BaseTools/Source/Python/Ecc/config.ini | 242 + BaseTools/Source/Python/Ecc/exception.xml | 310 + BaseTools/Source/Python/Fdb/__init__.py | 0 BaseTools/Source/Python/FixFlash/__init__.py | 0 BaseTools/Source/Python/GNUmakefile | 6 + BaseTools/Source/Python/GenFds/AprioriSection.py | 118 + BaseTools/Source/Python/GenFds/Attribute.py | 28 + BaseTools/Source/Python/GenFds/Capsule.py | 89 + BaseTools/Source/Python/GenFds/CapsuleData.py | 84 + .../Source/Python/GenFds/ComponentStatement.py | 29 + BaseTools/Source/Python/GenFds/CompressSection.py | 87 + BaseTools/Source/Python/GenFds/DataSection.py | 109 + BaseTools/Source/Python/GenFds/DepexSection.py | 102 + BaseTools/Source/Python/GenFds/EfiSection.py | 262 + BaseTools/Source/Python/GenFds/Fd.py | 169 + BaseTools/Source/Python/GenFds/FdfParser.py | 3778 ++++ BaseTools/Source/Python/GenFds/Ffs.py | 81 + BaseTools/Source/Python/GenFds/FfsFileStatement.py | 118 + BaseTools/Source/Python/GenFds/FfsInfStatement.py | 582 + BaseTools/Source/Python/GenFds/Fv.py | 215 + BaseTools/Source/Python/GenFds/FvImageSection.py | 90 + BaseTools/Source/Python/GenFds/GenFds.py | 486 + .../Source/Python/GenFds/GenFdsGlobalVariable.py | 472 + BaseTools/Source/Python/GenFds/GuidSection.py | 190 + .../Source/Python/GenFds/OptRomFileStatement.py | 50 + .../Source/Python/GenFds/OptRomInfStatement.py | 147 + BaseTools/Source/Python/GenFds/OptionRom.py | 140 + BaseTools/Source/Python/GenFds/Region.py | 240 + BaseTools/Source/Python/GenFds/Rule.py | 29 + BaseTools/Source/Python/GenFds/RuleComplexFile.py | 30 + BaseTools/Source/Python/GenFds/RuleSimpleFile.py | 30 + BaseTools/Source/Python/GenFds/Section.py | 153 + BaseTools/Source/Python/GenFds/UiSection.py | 77 + BaseTools/Source/Python/GenFds/VerSection.py | 82 + BaseTools/Source/Python/GenFds/Vtf.py | 188 + BaseTools/Source/Python/GenFds/__init__.py | 0 BaseTools/Source/Python/Makefile | 89 + .../Python/MigrationMsa2Inf/AutoGenExterns.py | 369 + .../Python/MigrationMsa2Inf/MigrationMsa2Inf.py | 2477 +++ .../Source/Python/MigrationMsa2Inf/__init__.py | 0 BaseTools/Source/Python/MkBOM/__init__.py | 0 .../Source/Python/PackagingTool/DependencyRules.py | 185 + .../Source/Python/PackagingTool/InstallPkg.py | 309 + BaseTools/Source/Python/PackagingTool/IpiDb.py | 629 + BaseTools/Source/Python/PackagingTool/MkPkg.py | 294 + .../Source/Python/PackagingTool/PackageFile.py | 160 + BaseTools/Source/Python/PackagingTool/RmPkg.py | 218 + BaseTools/Source/Python/Table/Table.py | 120 + BaseTools/Source/Python/Table/TableDataModel.py | 95 + BaseTools/Source/Python/Table/TableDec.py | 108 + BaseTools/Source/Python/Table/TableDsc.py | 108 + BaseTools/Source/Python/Table/TableEotReport.py | 76 + BaseTools/Source/Python/Table/TableFdf.py | 108 + BaseTools/Source/Python/Table/TableFile.py | 91 + BaseTools/Source/Python/Table/TableFunction.py | 95 + BaseTools/Source/Python/Table/TableIdentifier.py | 90 + BaseTools/Source/Python/Table/TableInf.py | 114 + BaseTools/Source/Python/Table/TablePcd.py | 90 + BaseTools/Source/Python/Table/TableQuery.py | 66 + BaseTools/Source/Python/Table/TableReport.py | 123 + BaseTools/Source/Python/Table/__init__.py | 0 BaseTools/Source/Python/TargetTool/TargetTool.py | 261 + BaseTools/Source/Python/TargetTool/__init__.py | 0 BaseTools/Source/Python/Trim/Trim.py | 520 + .../Source/Python/Workspace/BuildClassObject.py | 364 + BaseTools/Source/Python/Workspace/MetaDataTable.py | 335 + .../Source/Python/Workspace/MetaFileParser.py | 1131 ++ BaseTools/Source/Python/Workspace/MetaFileTable.py | 275 + .../Source/Python/Workspace/WorkspaceDatabase.py | 2274 +++ BaseTools/Source/Python/Workspace/__init__.py | 0 BaseTools/Source/Python/build/__init__.py | 0 BaseTools/Source/Python/build/build.py | 1436 ++ .../Python/fpd2dsc/EdkIIWorkspaceGuidsInfo.py | 327 + BaseTools/Source/Python/fpd2dsc/LoadFpd.py | 1039 + .../Source/Python/fpd2dsc/MigrationUtilities.py | 563 + BaseTools/Source/Python/fpd2dsc/StoreDsc.py | 765 + BaseTools/Source/Python/fpd2dsc/__init__.py | 0 BaseTools/Source/Python/fpd2dsc/fpd2dsc.py | 116 + BaseTools/Source/Python/msa2inf/ConvertModule.py | 112 + .../Python/msa2inf/EdkIIWorkspaceGuidsInfo.py | 325 + BaseTools/Source/Python/msa2inf/LoadMsa.py | 747 + BaseTools/Source/Python/msa2inf/Msa2Inf.py | 44 + BaseTools/Source/Python/msa2inf/StoreInf.py | 442 + BaseTools/Source/Python/msa2inf/__init__.py | 0 BaseTools/Source/Python/spd2dec/ConvertPackage.py | 66 + BaseTools/Source/Python/spd2dec/LoadSpd.py | 273 + BaseTools/Source/Python/spd2dec/Spd2Dec.py | 46 + BaseTools/Source/Python/spd2dec/StoreDec.py | 247 + BaseTools/Source/Python/spd2dec/__init__.py | 0 148 files changed, 83492 insertions(+) create mode 100644 BaseTools/Source/Python/AutoGen/AutoGen.py create mode 100644 BaseTools/Source/Python/AutoGen/BuildEngine.py create mode 100644 BaseTools/Source/Python/AutoGen/GenC.py create mode 100644 BaseTools/Source/Python/AutoGen/GenDepex.py create mode 100644 BaseTools/Source/Python/AutoGen/GenMake.py create mode 100644 BaseTools/Source/Python/AutoGen/StrGather.py create mode 100644 BaseTools/Source/Python/AutoGen/UniClassObject.py create mode 100644 BaseTools/Source/Python/AutoGen/__init__.py create mode 100644 BaseTools/Source/Python/Common/BuildToolError.py create mode 100644 BaseTools/Source/Python/Common/DataType.py create mode 100644 BaseTools/Source/Python/Common/Database.py create mode 100644 BaseTools/Source/Python/Common/DecClassObject.py create mode 100644 BaseTools/Source/Python/Common/DecClassObjectLight.py create mode 100644 BaseTools/Source/Python/Common/Dictionary.py create mode 100644 BaseTools/Source/Python/Common/DscClassObject.py create mode 100644 BaseTools/Source/Python/Common/EdkIIWorkspace.py create mode 100644 BaseTools/Source/Python/Common/EdkIIWorkspaceBuild.py create mode 100644 BaseTools/Source/Python/Common/EdkLogger.py create mode 100644 BaseTools/Source/Python/Common/FdfClassObject.py create mode 100644 BaseTools/Source/Python/Common/FdfParserLite.py create mode 100644 BaseTools/Source/Python/Common/GlobalData.py create mode 100644 BaseTools/Source/Python/Common/Identification.py create mode 100644 BaseTools/Source/Python/Common/InfClassObject.py create mode 100644 BaseTools/Source/Python/Common/InfClassObjectLight.py create mode 100644 BaseTools/Source/Python/Common/MigrationUtilities.py create mode 100644 BaseTools/Source/Python/Common/Misc.py create mode 100644 BaseTools/Source/Python/Common/Parsing.py create mode 100644 BaseTools/Source/Python/Common/PyUtility.pyd create mode 100644 BaseTools/Source/Python/Common/String.py create mode 100644 BaseTools/Source/Python/Common/TargetTxtClassObject.py create mode 100644 BaseTools/Source/Python/Common/ToolDefClassObject.py create mode 100644 BaseTools/Source/Python/Common/XmlParser.py create mode 100644 BaseTools/Source/Python/Common/XmlRoutines.py create mode 100644 BaseTools/Source/Python/Common/__init__.py create mode 100644 BaseTools/Source/Python/CommonDataClass/CommonClass.py create mode 100644 BaseTools/Source/Python/CommonDataClass/DataClass.py create mode 100644 BaseTools/Source/Python/CommonDataClass/DistributionPackageClass.py create mode 100644 BaseTools/Source/Python/CommonDataClass/FdfClass.py create mode 100644 BaseTools/Source/Python/CommonDataClass/ModuleClass.py create mode 100644 BaseTools/Source/Python/CommonDataClass/PackageClass.py create mode 100644 BaseTools/Source/Python/CommonDataClass/PlatformClass.py create mode 100644 BaseTools/Source/Python/CommonDataClass/__init__.py create mode 100644 BaseTools/Source/Python/Ecc/C.g create mode 100644 BaseTools/Source/Python/Ecc/CLexer.py create mode 100644 BaseTools/Source/Python/Ecc/CParser.py create mode 100644 BaseTools/Source/Python/Ecc/Check.py create mode 100644 BaseTools/Source/Python/Ecc/CodeFragment.py create mode 100644 BaseTools/Source/Python/Ecc/CodeFragmentCollector.py create mode 100644 BaseTools/Source/Python/Ecc/Configuration.py create mode 100644 BaseTools/Source/Python/Ecc/Database.py create mode 100644 BaseTools/Source/Python/Ecc/Ecc.py create mode 100644 BaseTools/Source/Python/Ecc/EccGlobalData.py create mode 100644 BaseTools/Source/Python/Ecc/EccToolError.py create mode 100644 BaseTools/Source/Python/Ecc/Exception.py create mode 100644 BaseTools/Source/Python/Ecc/FileProfile.py create mode 100644 BaseTools/Source/Python/Ecc/MetaDataParser.py create mode 100644 BaseTools/Source/Python/Ecc/ParserWarning.py create mode 100644 BaseTools/Source/Python/Ecc/__init__.py create mode 100644 BaseTools/Source/Python/Ecc/c.py create mode 100644 BaseTools/Source/Python/Ecc/config.ini create mode 100644 BaseTools/Source/Python/Ecc/exception.xml create mode 100644 BaseTools/Source/Python/Fdb/__init__.py create mode 100644 BaseTools/Source/Python/FixFlash/__init__.py create mode 100644 BaseTools/Source/Python/GNUmakefile create mode 100644 BaseTools/Source/Python/GenFds/AprioriSection.py create mode 100644 BaseTools/Source/Python/GenFds/Attribute.py create mode 100644 BaseTools/Source/Python/GenFds/Capsule.py create mode 100644 BaseTools/Source/Python/GenFds/CapsuleData.py create mode 100644 BaseTools/Source/Python/GenFds/ComponentStatement.py create mode 100644 BaseTools/Source/Python/GenFds/CompressSection.py create mode 100644 BaseTools/Source/Python/GenFds/DataSection.py create mode 100644 BaseTools/Source/Python/GenFds/DepexSection.py create mode 100644 BaseTools/Source/Python/GenFds/EfiSection.py create mode 100644 BaseTools/Source/Python/GenFds/Fd.py create mode 100644 BaseTools/Source/Python/GenFds/FdfParser.py create mode 100644 BaseTools/Source/Python/GenFds/Ffs.py create mode 100644 BaseTools/Source/Python/GenFds/FfsFileStatement.py create mode 100644 BaseTools/Source/Python/GenFds/FfsInfStatement.py create mode 100644 BaseTools/Source/Python/GenFds/Fv.py create mode 100644 BaseTools/Source/Python/GenFds/FvImageSection.py create mode 100644 BaseTools/Source/Python/GenFds/GenFds.py create mode 100644 BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py create mode 100644 BaseTools/Source/Python/GenFds/GuidSection.py create mode 100644 BaseTools/Source/Python/GenFds/OptRomFileStatement.py create mode 100644 BaseTools/Source/Python/GenFds/OptRomInfStatement.py create mode 100644 BaseTools/Source/Python/GenFds/OptionRom.py create mode 100644 BaseTools/Source/Python/GenFds/Region.py create mode 100644 BaseTools/Source/Python/GenFds/Rule.py create mode 100644 BaseTools/Source/Python/GenFds/RuleComplexFile.py create mode 100644 BaseTools/Source/Python/GenFds/RuleSimpleFile.py create mode 100644 BaseTools/Source/Python/GenFds/Section.py create mode 100644 BaseTools/Source/Python/GenFds/UiSection.py create mode 100644 BaseTools/Source/Python/GenFds/VerSection.py create mode 100644 BaseTools/Source/Python/GenFds/Vtf.py create mode 100644 BaseTools/Source/Python/GenFds/__init__.py create mode 100644 BaseTools/Source/Python/Makefile create mode 100644 BaseTools/Source/Python/MigrationMsa2Inf/AutoGenExterns.py create mode 100644 BaseTools/Source/Python/MigrationMsa2Inf/MigrationMsa2Inf.py create mode 100644 BaseTools/Source/Python/MigrationMsa2Inf/__init__.py create mode 100644 BaseTools/Source/Python/MkBOM/__init__.py create mode 100644 BaseTools/Source/Python/PackagingTool/DependencyRules.py create mode 100644 BaseTools/Source/Python/PackagingTool/InstallPkg.py create mode 100644 BaseTools/Source/Python/PackagingTool/IpiDb.py create mode 100644 BaseTools/Source/Python/PackagingTool/MkPkg.py create mode 100644 BaseTools/Source/Python/PackagingTool/PackageFile.py create mode 100644 BaseTools/Source/Python/PackagingTool/RmPkg.py create mode 100644 BaseTools/Source/Python/Table/Table.py create mode 100644 BaseTools/Source/Python/Table/TableDataModel.py create mode 100644 BaseTools/Source/Python/Table/TableDec.py create mode 100644 BaseTools/Source/Python/Table/TableDsc.py create mode 100644 BaseTools/Source/Python/Table/TableEotReport.py create mode 100644 BaseTools/Source/Python/Table/TableFdf.py create mode 100644 BaseTools/Source/Python/Table/TableFile.py create mode 100644 BaseTools/Source/Python/Table/TableFunction.py create mode 100644 BaseTools/Source/Python/Table/TableIdentifier.py create mode 100644 BaseTools/Source/Python/Table/TableInf.py create mode 100644 BaseTools/Source/Python/Table/TablePcd.py create mode 100644 BaseTools/Source/Python/Table/TableQuery.py create mode 100644 BaseTools/Source/Python/Table/TableReport.py create mode 100644 BaseTools/Source/Python/Table/__init__.py create mode 100644 BaseTools/Source/Python/TargetTool/TargetTool.py create mode 100644 BaseTools/Source/Python/TargetTool/__init__.py create mode 100644 BaseTools/Source/Python/Trim/Trim.py create mode 100644 BaseTools/Source/Python/Workspace/BuildClassObject.py create mode 100644 BaseTools/Source/Python/Workspace/MetaDataTable.py create mode 100644 BaseTools/Source/Python/Workspace/MetaFileParser.py create mode 100644 BaseTools/Source/Python/Workspace/MetaFileTable.py create mode 100644 BaseTools/Source/Python/Workspace/WorkspaceDatabase.py create mode 100644 BaseTools/Source/Python/Workspace/__init__.py create mode 100644 BaseTools/Source/Python/build/__init__.py create mode 100644 BaseTools/Source/Python/build/build.py create mode 100644 BaseTools/Source/Python/fpd2dsc/EdkIIWorkspaceGuidsInfo.py create mode 100644 BaseTools/Source/Python/fpd2dsc/LoadFpd.py create mode 100644 BaseTools/Source/Python/fpd2dsc/MigrationUtilities.py create mode 100644 BaseTools/Source/Python/fpd2dsc/StoreDsc.py create mode 100644 BaseTools/Source/Python/fpd2dsc/__init__.py create mode 100644 BaseTools/Source/Python/fpd2dsc/fpd2dsc.py create mode 100644 BaseTools/Source/Python/msa2inf/ConvertModule.py create mode 100644 BaseTools/Source/Python/msa2inf/EdkIIWorkspaceGuidsInfo.py create mode 100644 BaseTools/Source/Python/msa2inf/LoadMsa.py create mode 100644 BaseTools/Source/Python/msa2inf/Msa2Inf.py create mode 100644 BaseTools/Source/Python/msa2inf/StoreInf.py create mode 100644 BaseTools/Source/Python/msa2inf/__init__.py create mode 100644 BaseTools/Source/Python/spd2dec/ConvertPackage.py create mode 100644 BaseTools/Source/Python/spd2dec/LoadSpd.py create mode 100644 BaseTools/Source/Python/spd2dec/Spd2Dec.py create mode 100644 BaseTools/Source/Python/spd2dec/StoreDec.py create mode 100644 BaseTools/Source/Python/spd2dec/__init__.py (limited to 'BaseTools/Source/Python') diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py new file mode 100644 index 0000000000..86f33fbd86 --- /dev/null +++ b/BaseTools/Source/Python/AutoGen/AutoGen.py @@ -0,0 +1,1919 @@ +## @file +# Generate AutoGen.h, AutoGen.c and *.depex files +# +# Copyright (c) 2007, 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 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 re +import os.path as path +import copy + +import GenC +import GenMake +import GenDepex + +from StrGather import * +from BuildEngine import BuildRule + +from Common.BuildToolError import * +from Common.DataType import * +from Common.Misc import * +from Common.String import * +import Common.GlobalData as GlobalData +from GenFds.FdfParser import * +from CommonDataClass.CommonClass import SkuInfoClass +from Workspace.BuildClassObject import * + +## Regular expression for splitting Dependency Expression stirng into tokens +gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)") + +## Mapping Makefile type +gMakeTypeMap = {"MSFT":"nmake", "GCC":"gmake"} + + +## Build rule configuration file +gBuildRuleFile = 'Conf/build_rule.txt' + +## default file name for AutoGen +gAutoGenCodeFileName = "AutoGen.c" +gAutoGenHeaderFileName = "AutoGen.h" +gAutoGenStringFileName = "%(module_name)sStrDefs.h" +gAutoGenDepexFileName = "%(module_name)s.depex" +gAutoGenSmmDepexFileName = "%(module_name)s.smm" + +## Base class for AutoGen +# +# This class just implements the cache mechanism of AutoGen objects. +# +class AutoGen(object): + # database to maintain the objects of xxxAutoGen + _CACHE_ = {} # (BuildTarget, ToolChain) : {ARCH : {platform file: AutoGen object}}} + + ## Factory method + # + # @param Class class object of real AutoGen class + # (WorkspaceAutoGen, ModuleAutoGen or PlatformAutoGen) + # @param Workspace Workspace directory or WorkspaceAutoGen object + # @param MetaFile The path of meta file + # @param Target Build target + # @param Toolchain Tool chain name + # @param Arch Target arch + # @param *args The specific class related parameters + # @param **kwargs The specific class related dict parameters + # + def __new__(Class, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs): + # check if the object has been created + Key = (Target, Toolchain) + if Key not in Class._CACHE_ or Arch not in Class._CACHE_[Key] \ + or MetaFile not in Class._CACHE_[Key][Arch]: + AutoGenObject = super(AutoGen, Class).__new__(Class) + # call real constructor + if not AutoGenObject._Init(Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs): + return None + if Key not in Class._CACHE_: + Class._CACHE_[Key] = {} + if Arch not in Class._CACHE_[Key]: + Class._CACHE_[Key][Arch] = {} + Class._CACHE_[Key][Arch][MetaFile] = AutoGenObject + else: + AutoGenObject = Class._CACHE_[Key][Arch][MetaFile] + + return AutoGenObject + + ## hash() operator + # + # The file path of platform file will be used to represent hash value of this object + # + # @retval int Hash value of the file path of platform file + # + def __hash__(self): + return hash(self.MetaFile) + + ## str() operator + # + # The file path of platform file will be used to represent this object + # + # @retval string String of platform file path + # + def __str__(self): + return str(self.MetaFile) + + ## "==" operator + def __eq__(self, Other): + return Other and self.MetaFile == Other + +## Workspace AutoGen class +# +# This class is used mainly to control the whole platform build for different +# architecture. This class will generate top level makefile. +# +class WorkspaceAutoGen(AutoGen): + ## Real constructor of WorkspaceAutoGen + # + # This method behaves the same as __init__ except that it needs explict invoke + # (in super class's __new__ method) + # + # @param WorkspaceDir Root directory of workspace + # @param ActivePlatform Meta-file of active platform + # @param Target Build target + # @param Toolchain Tool chain name + # @param ArchList List of architecture of current build + # @param MetaFileDb Database containing meta-files + # @param BuildConfig Configuration of build + # @param ToolDefinition Tool chain definitions + # @param FlashDefinitionFile File of flash definition + # @param Fds FD list to be generated + # @param Fvs FV 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=''): + self.MetaFile = ActivePlatform.MetaFile + self.WorkspaceDir = WorkspaceDir + self.Platform = ActivePlatform + self.BuildTarget = Target + self.ToolChain = Toolchain + self.ArchList = ArchList + self.SkuId = SkuId + + self.BuildDatabase = MetaFileDb + self.TargetTxt = BuildConfig + self.ToolDef = ToolDefinition + self.FdfFile = FlashDefinitionFile + self.FdTargetList = Fds + self.FvTargetList = Fvs + self.AutoGenObjectList = [] + + # there's many relative directory operations, so ... + os.chdir(self.WorkspaceDir) + + # parse FDF file to get PCDs in it, if any + if self.FdfFile != None and self.FdfFile != '': + Fdf = FdfParser(self.FdfFile.Path) + Fdf.ParseFile() + PcdSet = Fdf.Profile.PcdDict + ModuleList = Fdf.Profile.InfList + else: + PcdSet = {} + ModuleList = [] + + # apply SKU and inject PCDs from Flash Definition file + for Arch in self.ArchList: + Platform = self.BuildDatabase[self.MetaFile, Arch] + Platform.SkuName = self.SkuId + for Name, Guid in PcdSet: + Platform.AddPcd(Name, Guid, PcdSet[Name, Guid]) + + Pa = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch) + # + # Explicitly collect platform's dynamic PCDs + # + Pa.CollectPlatformDynamicPcds() + self.AutoGenObjectList.append(Pa) + + self._BuildDir = None + self._FvDir = None + self._MakeFileDir = None + self._BuildCommand = None + + return True + + def __repr__(self): + return "%s [%s]" % (self.MetaFile, ", ".join(self.ArchList)) + + ## Return the directory to store FV files + def _GetFvDir(self): + if self._FvDir == None: + self._FvDir = path.join(self.BuildDir, 'FV') + return self._FvDir + + ## Return the directory to store all intermediate and final files built + def _GetBuildDir(self): + return self.AutoGenObjectList[0].BuildDir + + ## Return the build output directory platform specifies + def _GetOutputDir(self): + return self.Platform.OutputDirectory + + ## Return platform name + def _GetName(self): + return self.Platform.PlatformName + + ## Return meta-file GUID + def _GetGuid(self): + return self.Platform.Guid + + ## Return platform version + def _GetVersion(self): + return self.Platform.Version + + ## Return paths of tools + def _GetToolDefinition(self): + return self.AutoGenObjectList[0].ToolDefinition + + ## Return directory of platform makefile + # + # @retval string Makefile directory + # + def _GetMakeFileDir(self): + if self._MakeFileDir == None: + self._MakeFileDir = self.BuildDir + return self._MakeFileDir + + ## Return build command string + # + # @retval string Build command string + # + def _GetBuildCommand(self): + if self._BuildCommand == None: + # BuildCommand should be all the same. So just get one from platform AutoGen + self._BuildCommand = self.AutoGenObjectList[0].BuildCommand + return self._BuildCommand + + ## Create makefile for the platform and mdoules in it + # + # @param CreateDepsMakeFile Flag indicating if the makefile for + # modules will be created as well + # + def CreateMakeFile(self, CreateDepsMakeFile=False): + # create makefile for platform + Makefile = GenMake.TopLevelMakefile(self) + if Makefile.Generate(): + EdkLogger.debug(EdkLogger.DEBUG_9, "Generated makefile for platform [%s] %s\n" % + (self.MetaFile, self.ArchList)) + else: + EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for platform [%s] %s\n" % + (self.MetaFile, self.ArchList)) + + if CreateDepsMakeFile: + for Pa in self.AutoGenObjectList: + Pa.CreateMakeFile(CreateDepsMakeFile) + + ## Create autogen code for platform and modules + # + # Since there's no autogen code for platform, this method will do nothing + # if CreateModuleCodeFile is set to False. + # + # @param CreateDepsCodeFile Flag indicating if creating module's + # autogen code file or not + # + def CreateCodeFile(self, CreateDepsCodeFile=False): + if not CreateDepsCodeFile: + return + for Pa in self.AutoGenObjectList: + Pa.CreateCodeFile(CreateDepsCodeFile) + + Name = property(_GetName) + Guid = property(_GetGuid) + Version = property(_GetVersion) + OutputDir = property(_GetOutputDir) + + ToolDefinition = property(_GetToolDefinition) # toolcode : tool path + + BuildDir = property(_GetBuildDir) + FvDir = property(_GetFvDir) + MakeFileDir = property(_GetMakeFileDir) + BuildCommand = property(_GetBuildCommand) + +## AutoGen class for platform +# +# PlatformAutoGen class will process the original information in platform +# file in order to generate makefile for platform. +# +class PlatformAutoGen(AutoGen): + # + # Used to store all PCDs for both PEI and DXE phase, in order to generate + # correct PCD database + # + _DynaPcdList_ = [] + _NonDynaPcdList_ = [] + + ## The real constructor of PlatformAutoGen + # + # This method is not supposed to be called by users of PlatformAutoGen. It's + # only used by factory method __new__() to do real initialization work for an + # object of PlatformAutoGen + # + # @param Workspace WorkspaceAutoGen object + # @param PlatformFile Platform file (DSC file) + # @param Target Build target (DEBUG, RELEASE) + # @param Toolchain Name of tool chain + # @param Arch arch of the platform supports + # + def _Init(self, Workspace, PlatformFile, Target, Toolchain, Arch): + EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen platform [%s] [%s]" % (PlatformFile, Arch)) + GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (PlatformFile, Arch, Toolchain, Target) + + self.MetaFile = PlatformFile + self.Workspace = Workspace + self.WorkspaceDir = Workspace.WorkspaceDir + self.ToolChain = Toolchain + self.BuildTarget = Target + self.Arch = Arch + self.SourceDir = PlatformFile.SubDir + self.SourceOverrideDir = None + self.FdTargetList = self.Workspace.FdTargetList + self.FvTargetList = self.Workspace.FvTargetList + + # flag indicating if the makefile/C-code file has been created or not + self.IsMakeFileCreated = False + self.IsCodeFileCreated = False + + self._Platform = None + self._Name = None + self._Guid = None + self._Version = None + + self._BuildRule = None + self._SourceDir = None + self._BuildDir = None + self._OutputDir = None + self._FvDir = None + self._MakeFileDir = None + self._FdfFile = None + + self._PcdTokenNumber = None # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber + self._DynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...] + self._NonDynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...] + + self._ToolDefinitions = None + self._ToolDefFile = None # toolcode : tool path + self._ToolChainFamily = None + self._BuildRuleFamily = None + self._BuildOption = None # toolcode : option + self._PackageList = None + self._ModuleAutoGenList = None + self._LibraryAutoGenList = None + self._BuildCommand = None + + # get the original module/package/platform objects + self.BuildDatabase = Workspace.BuildDatabase + return True + + def __repr__(self): + return "%s [%s]" % (self.MetaFile, self.Arch) + + ## Create autogen code for platform and modules + # + # Since there's no autogen code for platform, this method will do nothing + # if CreateModuleCodeFile is set to False. + # + # @param CreateModuleCodeFile Flag indicating if creating module's + # autogen code file or not + # + def CreateCodeFile(self, CreateModuleCodeFile=False): + # only module has code to be greated, so do nothing if CreateModuleCodeFile is False + if self.IsCodeFileCreated or not CreateModuleCodeFile: + return + + for Ma in self.ModuleAutoGenList: + Ma.CreateCodeFile(True) + + # don't do this twice + self.IsCodeFileCreated = True + + ## Create makefile for the platform and mdoules in it + # + # @param CreateModuleMakeFile Flag indicating if the makefile for + # modules will be created as well + # + def CreateMakeFile(self, CreateModuleMakeFile=False): + if CreateModuleMakeFile: + for ModuleFile in self.Platform.Modules: + Ma = ModuleAutoGen(self.Workspace, ModuleFile, self.BuildTarget, + self.ToolChain, self.Arch, self.MetaFile) + Ma.CreateMakeFile(True) + + # no need to create makefile for the platform more than once + if self.IsMakeFileCreated: + return + + # create makefile for platform + Makefile = GenMake.PlatformMakefile(self) + if Makefile.Generate(): + EdkLogger.debug(EdkLogger.DEBUG_9, "Generated makefile for platform [%s] [%s]\n" % + (self.MetaFile, self.Arch)) + else: + EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for platform [%s] [%s]\n" % + (self.MetaFile, self.Arch)) + self.IsMakeFileCreated = True + + ## Collect dynamic PCDs + # + # Gather dynamic PCDs list from each module and their settings from platform + # This interface should be invoked explicitly when platform action is created. + # + def CollectPlatformDynamicPcds(self): + # for gathering error information + NoDatumTypePcdList = set() + + self._GuidValue = {} + for F in self.Platform.Modules.keys(): + M = ModuleAutoGen(self.Workspace, F, self.BuildTarget, self.ToolChain, self.Arch, self.MetaFile) + #GuidValue.update(M.Guids) + for PcdFromModule in M.ModulePcdList+M.LibraryPcdList: + # make sure that the "VOID*" kind of datum has MaxDatumSize set + if PcdFromModule.DatumType == "VOID*" and PcdFromModule.MaxDatumSize == None: + NoDatumTypePcdList.add("%s.%s [%s]" % (PcdFromModule.TokenSpaceGuidCName, PcdFromModule.TokenCName, F)) + + if PcdFromModule.Type in GenC.gDynamicPcd or PcdFromModule.Type in GenC.gDynamicExPcd: + # + # If a dynamic PCD used by a PEM module/PEI module & DXE module, + # it should be stored in Pcd PEI database, If a dynamic only + # used by DXE module, it should be stored in DXE PCD database. + # The default Phase is DXE + # + if M.ModuleType in ["PEIM", "PEI_CORE"]: + PcdFromModule.Phase = "PEI" + if PcdFromModule not in self._DynaPcdList_: + self._DynaPcdList_.append(PcdFromModule) + elif PcdFromModule.Phase == 'PEI': + # overwrite any the same PCD existing, if Phase is PEI + Index = self._DynaPcdList_.index(PcdFromModule) + self._DynaPcdList_[Index] = PcdFromModule + elif PcdFromModule not in self._NonDynaPcdList_: + self._NonDynaPcdList_.append(PcdFromModule) + + # print out error information and break the build, if error found + if len(NoDatumTypePcdList) > 0: + NoDatumTypePcdListString = "\n\t\t".join(NoDatumTypePcdList) + EdkLogger.error("build", AUTOGEN_ERROR, "PCD setting error", + File=self.MetaFile, + ExtraData="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n" + % NoDatumTypePcdListString) + self._NonDynamicPcdList = self._NonDynaPcdList_ + self._DynamicPcdList = self._DynaPcdList_ + + # + # Sort dynamic PCD list to: + # 1) If PCD's datum type is VOID* and value is unicode string which starts with L, the PCD item should + # try to be put header of dynamicd List + # 2) If PCD is HII type, the PCD item should be put after unicode type PCD + # + # The reason of sorting is make sure the unicode string is in double-byte alignment in string table. + # + UnicodePcdArray = [] + HiiPcdArray = [] + OtherPcdArray = [] + for Pcd in self._DynamicPcdList: + # just pick the a value to determine whether is unicode string type + Sku = Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]] + PcdValue = Sku.DefaultValue + if Pcd.DatumType == 'VOID*' and PcdValue.startswith("L"): + # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex + UnicodePcdArray.append(Pcd) + elif len(Sku.VariableName) > 0: + # if found HII type PCD then insert to right of UnicodeIndex + HiiPcdArray.append(Pcd) + else: + OtherPcdArray.append(Pcd) + del self._DynamicPcdList[:] + self._DynamicPcdList.extend(UnicodePcdArray) + self._DynamicPcdList.extend(HiiPcdArray) + self._DynamicPcdList.extend(OtherPcdArray) + + + ## Return the platform build data object + def _GetPlatform(self): + if self._Platform == None: + self._Platform = self.BuildDatabase[self.MetaFile, self.Arch] + return self._Platform + + ## Return platform name + def _GetName(self): + return self.Platform.PlatformName + + ## Return the meta file GUID + def _GetGuid(self): + return self.Platform.Guid + + ## Return the platform version + def _GetVersion(self): + return self.Platform.Version + + ## Return the FDF file name + def _GetFdfFile(self): + if self._FdfFile == None: + if self.Workspace.FdfFile != "": + self._FdfFile= path.join(self.WorkspaceDir, self.Workspace.FdfFile) + else: + self._FdfFile = '' + return self._FdfFile + + ## Return the build output directory platform specifies + def _GetOutputDir(self): + return self.Platform.OutputDirectory + + ## Return the directory to store all intermediate and final files built + def _GetBuildDir(self): + if self._BuildDir == None: + if os.path.isabs(self.OutputDir): + self._BuildDir = path.join( + path.abspath(self.OutputDir), + self.BuildTarget + "_" + self.ToolChain, + ) + else: + self._BuildDir = path.join( + self.WorkspaceDir, + self.OutputDir, + self.BuildTarget + "_" + self.ToolChain, + ) + return self._BuildDir + + ## Return directory of platform makefile + # + # @retval string Makefile directory + # + def _GetMakeFileDir(self): + if self._MakeFileDir == None: + self._MakeFileDir = path.join(self.BuildDir, self.Arch) + return self._MakeFileDir + + ## Return build command string + # + # @retval string Build command string + # + def _GetBuildCommand(self): + if self._BuildCommand == None: + self._BuildCommand = [] + if "MAKE" in self.ToolDefinition and "PATH" in self.ToolDefinition["MAKE"]: + self._BuildCommand += SplitOption(self.ToolDefinition["MAKE"]["PATH"]) + if "FLAGS" in self.ToolDefinition["MAKE"]: + NewOption = self.ToolDefinition["MAKE"]["FLAGS"].strip() + if NewOption != '': + self._BuildCommand += SplitOption(NewOption) + return self._BuildCommand + + ## Get tool chain definition + # + # Get each tool defition for given tool chain from tools_def.txt and platform + # + def _GetToolDefinition(self): + if self._ToolDefinitions == None: + ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDictionary + if TAB_TOD_DEFINES_COMMAND_TYPE not in self.Workspace.ToolDef.ToolsDefTxtDatabase: + EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No tools found in configuration", + ExtraData="[%s]" % self.MetaFile) + self._ToolDefinitions = {} + DllPathList = set() + for Def in ToolDefinition: + Target, Tag, Arch, Tool, Attr = Def.split("_") + if Target != self.BuildTarget or Tag != self.ToolChain or Arch != self.Arch: + continue + + Value = ToolDefinition[Def] + # don't record the DLL + if Attr == "DLL": + DllPathList.add(Value) + continue + + if Tool not in self._ToolDefinitions: + self._ToolDefinitions[Tool] = {} + self._ToolDefinitions[Tool][Attr] = Value + + ToolsDef = '' + MakePath = '' + if GlobalData.gOptions.SilentMode and "MAKE" in self._ToolDefinitions: + if "FLAGS" not in self._ToolDefinitions["MAKE"]: + self._ToolDefinitions["MAKE"]["FLAGS"] = "" + self._ToolDefinitions["MAKE"]["FLAGS"] += " -s" + MakeFlags = '' + for Tool in self._ToolDefinitions: + for Attr in self._ToolDefinitions[Tool]: + Value = self._ToolDefinitions[Tool][Attr] + if Tool in self.BuildOption and Attr in self.BuildOption[Tool]: + # check if override is indicated + if self.BuildOption[Tool][Attr].startswith('='): + Value = self.BuildOption[Tool][Attr][1:] + else: + Value += " " + self.BuildOption[Tool][Attr] + + if Attr == "PATH": + # Don't put MAKE definition in the file + if Tool == "MAKE": + MakePath = Value + else: + ToolsDef += "%s = %s\n" % (Tool, Value) + elif Attr != "DLL": + # Don't put MAKE definition in the file + if Tool == "MAKE": + if Attr == "FLAGS": + MakeFlags = Value + else: + ToolsDef += "%s_%s = %s\n" % (Tool, Attr, Value) + ToolsDef += "\n" + + SaveFileOnChange(self.ToolDefinitionFile, ToolsDef) + for DllPath in DllPathList: + os.environ["PATH"] = DllPath + os.pathsep + os.environ["PATH"] + os.environ["MAKE_FLAGS"] = MakeFlags + + return self._ToolDefinitions + + ## Return the paths of tools + def _GetToolDefFile(self): + if self._ToolDefFile == None: + self._ToolDefFile = os.path.join(self.MakeFileDir, "TOOLS_DEF." + self.Arch) + return self._ToolDefFile + + ## Retrieve the toolchain family of given toolchain tag. Default to 'MSFT'. + def _GetToolChainFamily(self): + if self._ToolChainFamily == None: + ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase + if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \ + or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \ + or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain]: + EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \ + % self.ToolChain) + self._ToolChainFamily = "MSFT" + else: + self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain] + return self._ToolChainFamily + + def _GetBuildRuleFamily(self): + if self._BuildRuleFamily == None: + ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase + if TAB_TOD_DEFINES_BUILDRULEFAMILY not in ToolDefinition \ + or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY] \ + or not ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain]: + EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \ + % self.ToolChain) + self._BuildRuleFamily = "MSFT" + else: + self._BuildRuleFamily = ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain] + return self._BuildRuleFamily + + ## Return the build options specific to this platform + def _GetBuildOptions(self): + if self._BuildOption == None: + self._BuildOption = self._ExpandBuildOption(self.Platform.BuildOptions) + return self._BuildOption + + ## Parse build_rule.txt in $(WORKSPACE)/Conf/build_rule.txt + # + # @retval BuildRule object + # + def _GetBuildRule(self): + if self._BuildRule == None: + BuildRuleFile = None + if TAB_TAT_DEFINES_BUILD_RULE_CONF in self.Workspace.TargetTxt.TargetTxtDictionary: + BuildRuleFile = self.Workspace.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_BUILD_RULE_CONF] + if BuildRuleFile in [None, '']: + BuildRuleFile = gBuildRuleFile + self._BuildRule = BuildRule(BuildRuleFile) + return self._BuildRule + + ## Summarize the packages used by modules in this platform + def _GetPackageList(self): + if self._PackageList == None: + self._PackageList = set() + for La in self.LibraryAutoGenList: + self._PackageList.update(La.DependentPackageList) + for Ma in self.ModuleAutoGenList: + self._PackageList.update(Ma.DependentPackageList) + self._PackageList = list(self._PackageList) + return self._PackageList + + ## Get list of non-dynamic PCDs + def _GetNonDynamicPcdList(self): + return self._NonDynamicPcdList + + ## Get list of dynamic PCDs + def _GetDynamicPcdList(self): + return self._DynamicPcdList + + ## Generate Token Number for all PCD + def _GetPcdTokenNumbers(self): + if self._PcdTokenNumber == None: + self._PcdTokenNumber = sdict() + TokenNumber = 1 + for Pcd in self.DynamicPcdList: + if Pcd.Phase == "PEI": + EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber)) + self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber + TokenNumber += 1 + + for Pcd in self.DynamicPcdList: + if Pcd.Phase == "DXE": + EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber)) + self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber + TokenNumber += 1 + + for Pcd in self.NonDynamicPcdList: + self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber + TokenNumber += 1 + return self._PcdTokenNumber + + ## Summarize ModuleAutoGen objects of all modules/libraries to be built for this platform + def _GetAutoGenObjectList(self): + self._ModuleAutoGenList = [] + self._LibraryAutoGenList = [] + for ModuleFile in self.Platform.Modules: + Ma = ModuleAutoGen( + self.Workspace, + ModuleFile, + self.BuildTarget, + self.ToolChain, + self.Arch, + self.MetaFile + ) + if Ma not in self._ModuleAutoGenList: + self._ModuleAutoGenList.append(Ma) + for La in Ma.LibraryAutoGenList: + if La not in self._LibraryAutoGenList: + self._LibraryAutoGenList.append(La) + + ## Summarize ModuleAutoGen objects of all modules to be built for this platform + def _GetModuleAutoGenList(self): + if self._ModuleAutoGenList == None: + self._GetAutoGenObjectList() + return self._ModuleAutoGenList + + ## Summarize ModuleAutoGen objects of all libraries to be built for this platform + def _GetLibraryAutoGenList(self): + if self._LibraryAutoGenList == None: + self._GetAutoGenObjectList() + return self._LibraryAutoGenList + + ## Test if a module is supported by the platform + # + # An error will be raised directly if the module or its arch is not supported + # by the platform or current configuration + # + def ValidModule(self, Module): + return Module in self.Platform.Modules or Module in self.Platform.LibraryInstances + + ## Resolve the library classes in a module to library instances + # + # This method will not only resolve library classes but also sort the library + # instances according to the dependency-ship. + # + # @param Module The module from which the library classes will be resolved + # + # @retval library_list List of library instances sorted + # + def ApplyLibraryInstance(self, Module): + ModuleType = Module.ModuleType + + # for overridding library instances with module specific setting + PlatformModule = self.Platform.Modules[str(Module)] + + # add forced library instance + for LibraryClass in PlatformModule.LibraryClasses: + if LibraryClass.startswith("NULL"): + Module.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass] + + # R9 module + LibraryConsumerList = [Module] + Constructor = [] + ConsumedByList = sdict() + LibraryInstance = sdict() + + EdkLogger.verbose("") + EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch)) + while len(LibraryConsumerList) > 0: + M = LibraryConsumerList.pop() + for LibraryClassName in M.LibraryClasses: + if LibraryClassName not in LibraryInstance: + # override library instance for this module + if LibraryClassName in PlatformModule.LibraryClasses: + LibraryPath = PlatformModule.LibraryClasses[LibraryClassName] + else: + LibraryPath = self.Platform.LibraryClasses[LibraryClassName, ModuleType] + if LibraryPath == None or LibraryPath == "": + LibraryPath = M.LibraryClasses[LibraryClassName] + if LibraryPath == None or LibraryPath == "": + EdkLogger.error("build", RESOURCE_NOT_AVAILABLE, + "Instance of library class [%s] is not found" % LibraryClassName, + File=self.MetaFile, + ExtraData="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M), self.Arch, str(Module))) + + LibraryModule = self.BuildDatabase[LibraryPath, self.Arch] + # for those forced library instance (NULL library), add a fake library class + if LibraryClassName.startswith("NULL"): + LibraryModule.LibraryClass.append(LibraryClassObject(LibraryClassName, [ModuleType])) + elif LibraryModule.LibraryClass == None \ + or len(LibraryModule.LibraryClass) == 0 \ + or (ModuleType != 'USER_DEFINED' + and ModuleType not in LibraryModule.LibraryClass[0].SupModList): + # only USER_DEFINED can link against any library instance despite of its SupModList + EdkLogger.error("build", OPTION_MISSING, + "Module type [%s] is not supported by library instance [%s]" \ + % (ModuleType, LibraryPath), File=self.MetaFile, + ExtraData="consumed by [%s]" % str(Module)) + + LibraryInstance[LibraryClassName] = LibraryModule + LibraryConsumerList.append(LibraryModule) + EdkLogger.verbose("\t" + str(LibraryClassName) + " : " + str(LibraryModule)) + else: + LibraryModule = LibraryInstance[LibraryClassName] + + if LibraryModule == None: + continue + + if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor: + Constructor.append(LibraryModule) + + if LibraryModule not in ConsumedByList: + ConsumedByList[LibraryModule] = [] + # don't add current module itself to consumer list + if M != Module: + if M in ConsumedByList[LibraryModule]: + continue + ConsumedByList[LibraryModule].append(M) + # + # Initialize the sorted output list to the empty set + # + SortedLibraryList = [] + # + # Q <- Set of all nodes with no incoming edges + # + LibraryList = [] #LibraryInstance.values() + Q = [] + for LibraryClassName in LibraryInstance: + M = LibraryInstance[LibraryClassName] + LibraryList.append(M) + if ConsumedByList[M] == []: + Q.insert(0, M) + + # + # start the DAG algorithm + # + while True: + EdgeRemoved = True + while Q == [] and EdgeRemoved: + EdgeRemoved = False + # for each node Item with a Constructor + for Item in LibraryList: + if Item not in Constructor: + continue + # for each Node without a constructor with an edge e from Item to Node + for Node in ConsumedByList[Item]: + if Node in Constructor: + continue + # remove edge e from the graph if Node has no constructor + ConsumedByList[Item].remove(Node) + EdgeRemoved = True + if ConsumedByList[Item] == []: + # insert Item into Q + Q.insert(0, Item) + break + if Q != []: + break + # DAG is done if there's no more incoming edge for all nodes + if Q == []: + break + + # remove node from Q + Node = Q.pop() + # output Node + SortedLibraryList.append(Node) + + # for each node Item with an edge e from Node to Item do + for Item in LibraryList: + if Node not in ConsumedByList[Item]: + continue + # remove edge e from the graph + ConsumedByList[Item].remove(Node) + + if ConsumedByList[Item] != []: + continue + # insert Item into Q, if Item has no other incoming edges + Q.insert(0, Item) + + # + # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle + # + for Item in LibraryList: + if ConsumedByList[Item] != [] and Item in Constructor and len(Constructor) > 1: + ErrorMessage = "\tconsumed by " + "\n\tconsumed by ".join([str(L) for L in ConsumedByList[Item]]) + EdkLogger.error("build", BUILD_ERROR, 'Library [%s] with constructors has a cycle' % str(Item), + ExtraData=ErrorMessage, File=self.MetaFile) + if Item not in SortedLibraryList: + SortedLibraryList.append(Item) + + # + # Build the list of constructor and destructir names + # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order + # + SortedLibraryList.reverse() + return SortedLibraryList + + + ## Override PCD setting (type, value, ...) + # + # @param ToPcd The PCD to be overrided + # @param FromPcd The PCD overrideing from + # + def _OverridePcd(self, ToPcd, FromPcd, Module=""): + # + # in case there's PCDs coming from FDF file, which have no type given. + # at this point, ToPcd.Type has the type found from dependent + # package + # + if FromPcd != None: + if ToPcd.Pending and FromPcd.Type not in [None, '']: + ToPcd.Type = FromPcd.Type + elif ToPcd.Type not in [None, ''] and FromPcd.Type not in [None, ''] \ + and ToPcd.Type != FromPcd.Type: + EdkLogger.error("build", OPTION_CONFLICT, "Mismatched PCD type", + ExtraData="%s.%s is defined as [%s] in module %s, but as [%s] in platform."\ + % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName, + ToPcd.Type, Module, FromPcd.Type), + File=self.MetaFile) + + if FromPcd.MaxDatumSize not in [None, '']: + ToPcd.MaxDatumSize = FromPcd.MaxDatumSize + if FromPcd.DefaultValue not in [None, '']: + ToPcd.DefaultValue = FromPcd.DefaultValue + if FromPcd.TokenValue not in [None, '']: + ToPcd.TokenValue = FromPcd.TokenValue + if FromPcd.MaxDatumSize not in [None, '']: + ToPcd.MaxDatumSize = FromPcd.MaxDatumSize + if FromPcd.DatumType not in [None, '']: + ToPcd.DatumType = FromPcd.DatumType + if FromPcd.SkuInfoList not in [None, '', []]: + ToPcd.SkuInfoList = FromPcd.SkuInfoList + + # check the validation of datum + IsValid, Cause = CheckPcdDatum(ToPcd.DatumType, ToPcd.DefaultValue) + if not IsValid: + EdkLogger.error('build', FORMAT_INVALID, Cause, File=self.MetaFile, + ExtraData="%s.%s" % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName)) + + if ToPcd.DatumType == "VOID*" and ToPcd.MaxDatumSize in ['', None]: + EdkLogger.debug(EdkLogger.DEBUG_9, "No MaxDatumSize specified for PCD %s.%s" \ + % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName)) + Value = ToPcd.DefaultValue + if Value in [None, '']: + ToPcd.MaxDatumSize = 1 + elif Value[0] == 'L': + ToPcd.MaxDatumSize = str(len(Value) * 2) + elif Value[0] == '{': + ToPcd.MaxDatumSize = str(len(Value.split(','))) + else: + ToPcd.MaxDatumSize = str(len(Value)) + + # apply default SKU for dynamic PCDS if specified one is not available + if (ToPcd.Type in PCD_DYNAMIC_TYPE_LIST or ToPcd.Type in PCD_DYNAMIC_EX_TYPE_LIST) \ + and ToPcd.SkuInfoList in [None, {}, '']: + if self.Platform.SkuName in self.Platform.SkuIds: + SkuName = self.Platform.SkuName + else: + SkuName = 'DEFAULT' + ToPcd.SkuInfoList = { + SkuName : SkuInfoClass(SkuName, self.Platform.SkuIds[SkuName], '', '', '', '', '', ToPcd.DefaultValue) + } + + ## Apply PCD setting defined platform to a module + # + # @param Module The module from which the PCD setting will be overrided + # + # @retval PCD_list The list PCDs with settings from platform + # + def ApplyPcdSetting(self, Module, Pcds): + # for each PCD in module + for Name,Guid in Pcds: + PcdInModule = Pcds[Name,Guid] + # find out the PCD setting in platform + if (Name,Guid) in self.Platform.Pcds: + PcdInPlatform = self.Platform.Pcds[Name,Guid] + else: + PcdInPlatform = None + # then override the settings if any + self._OverridePcd(PcdInModule, PcdInPlatform, Module) + # resolve the VariableGuid value + for SkuId in PcdInModule.SkuInfoList: + Sku = PcdInModule.SkuInfoList[SkuId] + if Sku.VariableGuid == '': continue + Sku.VariableGuidValue = GuidValue(Sku.VariableGuid, self.PackageList) + if Sku.VariableGuidValue == None: + PackageList = "\n\t".join([str(P) for P in self.PackageList]) + EdkLogger.error( + 'build', + RESOURCE_NOT_AVAILABLE, + "Value of GUID [%s] is not found in" % Sku.VariableGuid, + ExtraData=PackageList + "\n\t(used with %s.%s from module %s)" \ + % (Guid, Name, str(Module)), + File=self.MetaFile + ) + + # override PCD settings with module specific setting + if Module in self.Platform.Modules: + PlatformModule = self.Platform.Modules[str(Module)] + for Key in PlatformModule.Pcds: + if Key in Pcds: + self._OverridePcd(Pcds[Key], PlatformModule.Pcds[Key], Module) + return Pcds.values() + + ## Resolve library names to library modules + # + # (for R8.x modules) + # + # @param Module The module from which the library names will be resolved + # + # @retval library_list The list of library modules + # + def ResolveLibraryReference(self, Module): + EdkLogger.verbose("") + EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch)) + LibraryConsumerList = [Module] + + # "CompilerStub" is a must for R8 modules + if Module.Libraries: + Module.Libraries.append("CompilerStub") + LibraryList = [] + while len(LibraryConsumerList) > 0: + M = LibraryConsumerList.pop() + for LibraryName in M.Libraries: + Library = self.Platform.LibraryClasses[LibraryName, ':dummy:'] + if Library == None: + for Key in self.Platform.LibraryClasses.data.keys(): + if LibraryName.upper() == Key.upper(): + Library = self.Platform.LibraryClasses[Key, ':dummy:'] + break + if Library == None: + EdkLogger.warn("build", "Library [%s] is not found" % LibraryName, File=str(M), + ExtraData="\t%s [%s]" % (str(Module), self.Arch)) + continue + + if Library not in LibraryList: + LibraryList.append(Library) + LibraryConsumerList.append(Library) + EdkLogger.verbose("\t" + LibraryName + " : " + str(Library) + ' ' + str(type(Library))) + return LibraryList + + ## Expand * in build option key + # + # @param Options Options to be expanded + # + # @retval options Options expanded + # + def _ExpandBuildOption(self, Options): + BuildOptions = {} + for Key in Options: + Family = Key[0] + Target, Tag, Arch, Tool, Attr = Key[1].split("_") + # if tool chain family doesn't match, skip it + if Family and Tool in self.ToolDefinition and Family != self.ToolDefinition[Tool]["FAMILY"]: + continue + # expand any wildcard + if Target == "*" or Target == self.BuildTarget: + if Tag == "*" or Tag == self.ToolChain: + if Arch == "*" or Arch == self.Arch: + if Tool not in BuildOptions: + BuildOptions[Tool] = {} + if Attr != "FLAGS" or Attr not in BuildOptions[Tool]: + BuildOptions[Tool][Attr] = Options[Key] + else: + # append options for the same tool + BuildOptions[Tool][Attr] += " " + Options[Key] + return BuildOptions + + ## Append build options in platform to a module + # + # @param Module The module to which the build options will be appened + # + # @retval options The options appended with build options in platform + # + def ApplyBuildOption(self, Module): + PlatformOptions = self.BuildOption + ModuleOptions = self._ExpandBuildOption(Module.BuildOptions) + if Module in self.Platform.Modules: + PlatformModule = self.Platform.Modules[str(Module)] + PlatformModuleOptions = self._ExpandBuildOption(PlatformModule.BuildOptions) + else: + PlatformModuleOptions = {} + + AllTools = set(ModuleOptions.keys() + PlatformOptions.keys() + PlatformModuleOptions.keys() + self.ToolDefinition.keys()) + BuildOptions = {} + for Tool in AllTools: + if Tool not in BuildOptions: + BuildOptions[Tool] = {} + + for Options in [self.ToolDefinition, ModuleOptions, PlatformOptions, PlatformModuleOptions]: + if Tool not in Options: + continue + for Attr in Options[Tool]: + Value = Options[Tool][Attr] + if Attr not in BuildOptions[Tool]: + BuildOptions[Tool][Attr] = "" + # check if override is indicated + if Value.startswith('='): + BuildOptions[Tool][Attr] = Value[1:] + else: + BuildOptions[Tool][Attr] += " " + Value + return BuildOptions + + Platform = property(_GetPlatform) + Name = property(_GetName) + Guid = property(_GetGuid) + Version = property(_GetVersion) + + OutputDir = property(_GetOutputDir) + BuildDir = property(_GetBuildDir) + MakeFileDir = property(_GetMakeFileDir) + FdfFile = property(_GetFdfFile) + + PcdTokenNumber = property(_GetPcdTokenNumbers) # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber + DynamicPcdList = property(_GetDynamicPcdList) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...] + NonDynamicPcdList = property(_GetNonDynamicPcdList) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...] + PackageList = property(_GetPackageList) + + ToolDefinition = property(_GetToolDefinition) # toolcode : tool path + ToolDefinitionFile = property(_GetToolDefFile) # toolcode : lib path + ToolChainFamily = property(_GetToolChainFamily) + BuildRuleFamily = property(_GetBuildRuleFamily) + BuildOption = property(_GetBuildOptions) # toolcode : option + + BuildCommand = property(_GetBuildCommand) + BuildRule = property(_GetBuildRule) + ModuleAutoGenList = property(_GetModuleAutoGenList) + LibraryAutoGenList = property(_GetLibraryAutoGenList) + +## ModuleAutoGen class +# +# This class encapsules the AutoGen behaviors for the build tools. In addition to +# the generation of AutoGen.h and AutoGen.c, it will generate *.depex file according +# to the [depex] section in module's inf file. +# +class ModuleAutoGen(AutoGen): + ## The real constructor of ModuleAutoGen + # + # This method is not supposed to be called by users of ModuleAutoGen. It's + # only used by factory method __new__() to do real initialization work for an + # object of ModuleAutoGen + # + # @param Workspace EdkIIWorkspaceBuild object + # @param ModuleFile The path of module file + # @param Target Build target (DEBUG, RELEASE) + # @param Toolchain Name of tool chain + # @param Arch The arch the module supports + # @param PlatformFile Platform meta-file + # + def _Init(self, Workspace, ModuleFile, Target, Toolchain, Arch, PlatformFile): + EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen module [%s] [%s]" % (ModuleFile, Arch)) + GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (ModuleFile, Arch, Toolchain, Target) + + self.Workspace = Workspace + self.WorkspaceDir = Workspace.WorkspaceDir + + self.MetaFile = ModuleFile + self.PlatformInfo = PlatformAutoGen(Workspace, PlatformFile, Target, Toolchain, Arch) + # check if this module is employed by active platform + if not self.PlatformInfo.ValidModule(self.MetaFile): + EdkLogger.verbose("Module [%s] for [%s] is not employed by active platform\n" \ + % (self.MetaFile, Arch)) + return False + + self.SourceDir = self.MetaFile.SubDir + self.SourceOverrideDir = None + # use overrided path defined in DSC file + if self.MetaFile.Key in GlobalData.gOverrideDir: + self.SourceOverrideDir = GlobalData.gOverrideDir[self.MetaFile.Key] + + self.ToolChain = Toolchain + self.BuildTarget = Target + self.Arch = Arch + self.ToolChainFamily = self.PlatformInfo.ToolChainFamily + self.BuildRuleFamily = self.PlatformInfo.BuildRuleFamily + + self.IsMakeFileCreated = False + self.IsCodeFileCreated = False + + self.BuildDatabase = self.Workspace.BuildDatabase + + self._Module = None + self._Name = None + self._Guid = None + self._Version = None + self._ModuleType = None + self._ComponentType = None + self._PcdIsDriver = None + self._AutoGenVersion = None + self._LibraryFlag = None + self._CustomMakefile = None + self._Macro = None + + self._BuildDir = None + self._OutputDir = None + self._DebugDir = None + self._MakeFileDir = None + + self._IncludePathList = None + self._AutoGenFileList = None + self._UnicodeFileList = None + self._SourceFileList = None + self._ObjectFileList = None + self._BinaryFileList = None + + self._DependentPackageList = None + self._DependentLibraryList = None + self._LibraryAutoGenList = None + self._DerivedPackageList = None + self._ModulePcdList = None + self._LibraryPcdList = None + self._GuidList = None + self._ProtocolList = None + self._PpiList = None + self._DepexList = None + self._BuildOption = None + self._BuildTargets = None + self._IntroBuildTargetList = None + self._FinalBuildTargetList = None + self._FileTypes = None + self._BuildRules = None + + return True + + def __repr__(self): + return "%s [%s]" % (self.MetaFile, self.Arch) + + # Macros could be used in build_rule.txt (also Makefile) + def _GetMacros(self): + if self._Macro == None: + self._Macro = sdict() + self._Macro["WORKSPACE" ] = self.WorkspaceDir + self._Macro["MODULE_NAME" ] = self.Name + self._Macro["MODULE_GUID" ] = self.Guid + self._Macro["MODULE_VERSION" ] = self.Version + self._Macro["MODULE_TYPE" ] = self.ModuleType + self._Macro["MODULE_FILE" ] = str(self.MetaFile) + self._Macro["MODULE_FILE_BASE_NAME" ] = self.MetaFile.BaseName + self._Macro["MODULE_RELATIVE_DIR" ] = self.SourceDir + self._Macro["MODULE_DIR" ] = self.SourceDir + + self._Macro["BASE_NAME" ] = self.Name + + self._Macro["ARCH" ] = self.Arch + self._Macro["TOOLCHAIN" ] = self.ToolChain + self._Macro["TOOLCHAIN_TAG" ] = self.ToolChain + self._Macro["TARGET" ] = self.BuildTarget + + self._Macro["BUILD_DIR" ] = self.PlatformInfo.BuildDir + self._Macro["BIN_DIR" ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch) + self._Macro["LIB_DIR" ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch) + self._Macro["MODULE_BUILD_DIR" ] = self.BuildDir + self._Macro["OUTPUT_DIR" ] = self.OutputDir + self._Macro["DEBUG_DIR" ] = self.DebugDir + return self._Macro + + ## Return the module build data object + def _GetModule(self): + if self._Module == None: + self._Module = self.Workspace.BuildDatabase[self.MetaFile, self.Arch] + return self._Module + + ## Return the module name + def _GetBaseName(self): + return self.Module.BaseName + + ## Return the module SourceOverridePath + def _GetSourceOverridePath(self): + return self.Module.SourceOverridePath + + ## Return the module meta-file GUID + def _GetGuid(self): + return self.Module.Guid + + ## Return the module version + def _GetVersion(self): + return self.Module.Version + + ## Return the module type + def _GetModuleType(self): + return self.Module.ModuleType + + ## Return the component type (for R8.x style of module) + def _GetComponentType(self): + return self.Module.ComponentType + + ## Return the build type + def _GetBuildType(self): + return self.Module.BuildType + + ## Return the PCD_IS_DRIVER setting + def _GetPcdIsDriver(self): + return self.Module.PcdIsDriver + + ## Return the autogen version, i.e. module meta-file version + def _GetAutoGenVersion(self): + return self.Module.AutoGenVersion + + ## Check if the module is library or not + def _IsLibrary(self): + if self._LibraryFlag == None: + if self.Module.LibraryClass != None and self.Module.LibraryClass != []: + self._LibraryFlag = True + else: + self._LibraryFlag = False + return self._LibraryFlag + + ## Return the directory to store intermediate files of the module + def _GetBuildDir(self): + if self._BuildDir == None: + self._BuildDir = path.join( + self.PlatformInfo.BuildDir, + self.Arch, + self.SourceDir, + self.MetaFile.BaseName + ) + CreateDirectory(self._BuildDir) + return self._BuildDir + + ## Return the directory to store the intermediate object files of the mdoule + def _GetOutputDir(self): + if self._OutputDir == None: + self._OutputDir = path.join(self.BuildDir, "OUTPUT") + CreateDirectory(self._OutputDir) + return self._OutputDir + + ## Return the directory to store auto-gened source files of the mdoule + def _GetDebugDir(self): + if self._DebugDir == None: + self._DebugDir = path.join(self.BuildDir, "DEBUG") + CreateDirectory(self._DebugDir) + return self._DebugDir + + ## Return the path of custom file + def _GetCustomMakefile(self): + if self._CustomMakefile == None: + self._CustomMakefile = {} + for Type in self.Module.CustomMakefile: + if Type in gMakeTypeMap: + MakeType = gMakeTypeMap[Type] + else: + MakeType = 'nmake' + if self.SourceOverrideDir != None: + File = os.path.join(self.SourceOverrideDir, self.Module.CustomMakefile[Type]) + if not os.path.exists(File): + File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type]) + else: + File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type]) + self._CustomMakefile[MakeType] = File + return self._CustomMakefile + + ## Return the directory of the makefile + # + # @retval string The directory string of module's makefile + # + def _GetMakeFileDir(self): + return self.BuildDir + + ## Return build command string + # + # @retval string Build command string + # + def _GetBuildCommand(self): + return self.PlatformInfo.BuildCommand + + ## Get object list of all packages the module and its dependent libraries belong to + # + # @retval list The list of package object + # + def _GetDerivedPackageList(self): + PackageList = [] + for M in [self.Module] + self.DependentLibraryList: + for Package in M.Packages: + if Package in PackageList: + continue + PackageList.append(Package) + return PackageList + + ## Merge dependency expression + # + # @retval list The token list of the dependency expression after parsed + # + def _GetDepexTokenList(self): + if self._DepexList == None: + self._DepexList = {} + if self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes: + return self._DepexList + + if self.ModuleType == "DXE_SMM_DRIVER": + self._DepexList["DXE_DRIVER"] = [] + self._DepexList["SMM_DRIVER"] = [] + else: + self._DepexList[self.ModuleType] = [] + + for ModuleType in self._DepexList: + DepexList = self._DepexList[ModuleType] + # + # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion + # + for M in [self.Module] + self.DependentLibraryList: + Inherited = False + for D in M.Depex[self.Arch, ModuleType]: + if DepexList != []: + DepexList.append('AND') + DepexList.append('(') + DepexList.extend(D) + if DepexList[-1] == 'END': # no need of a END at this time + DepexList.pop() + DepexList.append(')') + Inherited = True + if Inherited: + EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.BaseName, DepexList)) + if 'BEFORE' in DepexList or 'AFTER' in DepexList: + break + if len(DepexList) > 0: + EdkLogger.verbose('') + return self._DepexList + + ## Return the list of specification version required for the module + # + # @retval list The list of specification defined in module file + # + def _GetSpecification(self): + return self.Module.Specification + + ## Tool option for the module build + # + # @param PlatformInfo The object of PlatformBuildInfo + # @retval dict The dict containing valid options + # + def _GetModuleBuildOption(self): + if self._BuildOption == None: + self._BuildOption = self.PlatformInfo.ApplyBuildOption(self.Module) + return self._BuildOption + + ## Return a list of files which can be built from source + # + # What kind of files can be built is determined by build rules in + # $(WORKSPACE)/Conf/build_rule.txt and toolchain family. + # + def _GetSourceFileList(self): + if self._SourceFileList == None: + self._SourceFileList = [] + for F in self.Module.Sources: + # match tool chain + if F.TagName != "" and F.TagName != self.ToolChain: + EdkLogger.debug(EdkLogger.DEBUG_9, "The toolchain [%s] for processing file [%s] is found, " + "but [%s] is needed" % (F.TagName, str(F), self.ToolChain)) + continue + # match tool chain family + if F.ToolChainFamily != "" and F.ToolChainFamily != self.ToolChainFamily: + EdkLogger.debug( + EdkLogger.DEBUG_0, + "The file [%s] must be built by tools of [%s], " \ + "but current toolchain family is [%s]" \ + % (str(F), F.ToolChainFamily, self.ToolChainFamily)) + continue + + # add the file path into search path list for file including + if F.Dir not in self.IncludePathList and self.AutoGenVersion >= 0x00010005: + self.IncludePathList.insert(0, F.Dir) + self._SourceFileList.append(F) + self._ApplyBuildRule(F, TAB_UNKNOWN_FILE) + return self._SourceFileList + + ## Return the list of unicode files + def _GetUnicodeFileList(self): + if self._UnicodeFileList == None: + if TAB_UNICODE_FILE in self.FileTypes: + self._UnicodeFileList = self.FileTypes[TAB_UNICODE_FILE] + else: + self._UnicodeFileList = [] + return self._UnicodeFileList + + ## Return a list of files which can be built from binary + # + # "Build" binary files are just to copy them to build directory. + # + # @retval list The list of files which can be built later + # + def _GetBinaryFiles(self): + if self._BinaryFileList == None: + self._BinaryFileList = [] + for F in self.Module.Binaries: + if F.Target not in ['COMMON', '*'] and F.Target != self.BuildTarget: + continue + self._BinaryFileList.append(F) + self._ApplyBuildRule(F, F.Type) + return self._BinaryFileList + + def _GetBuildRules(self): + if self._BuildRules == None: + BuildRules = {} + BuildRuleDatabase = self.PlatformInfo.BuildRule + for Type in BuildRuleDatabase.FileTypeList: + #first try getting build rule by BuildRuleFamily + RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.BuildRuleFamily] + if not RuleObject: + # build type is always module type, but ... + if self.ModuleType != self.BuildType: + RuleObject = BuildRuleDatabase[Type, self.ModuleType, self.Arch, self.BuildRuleFamily] + #second try getting build rule by ToolChainFamily + if not RuleObject: + RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.ToolChainFamily] + if not RuleObject: + # build type is always module type, but ... + if self.ModuleType != self.BuildType: + RuleObject = BuildRuleDatabase[Type, self.ModuleType, self.Arch, self.ToolChainFamily] + if not RuleObject: + continue + RuleObject = RuleObject.Instantiate(self.Macros) + BuildRules[Type] = RuleObject + for Ext in RuleObject.SourceFileExtList: + BuildRules[Ext] = RuleObject + self._BuildRules = BuildRules + return self._BuildRules + + def _ApplyBuildRule(self, File, FileType): + if self._BuildTargets == None: + self._IntroBuildTargetList = set() + self._FinalBuildTargetList = set() + self._BuildTargets = {} + self._FileTypes = {} + + LastTarget = None + RuleChain = [] + SourceList = [File] + Index = 0 + while Index < len(SourceList): + Source = SourceList[Index] + Index = Index + 1 + + if Source != File: + CreateDirectory(Source.Dir) + + if FileType in self.BuildRules: + RuleObject = self.BuildRules[FileType] + elif Source.Ext in self.BuildRules: + RuleObject = self.BuildRules[Source.Ext] + elif File.IsBinary and File == Source: + RuleObject = self.BuildRules[TAB_DEFAULT_BINARY_FILE] + else: + # stop at no more rules + if LastTarget: + self._FinalBuildTargetList.add(LastTarget) + break + + FileType = RuleObject.SourceFileType + if FileType not in self._FileTypes: + self._FileTypes[FileType] = set() + self._FileTypes[FileType].add(Source) + + # stop at STATIC_LIBRARY for library + if self.IsLibrary and FileType == TAB_STATIC_LIBRARY: + self._FinalBuildTargetList.add(LastTarget) + break + + Target = RuleObject.Apply(Source) + if not Target: + if LastTarget: + self._FinalBuildTargetList.add(LastTarget) + break + elif not Target.Outputs: + # Only do build for target with outputs + self._FinalBuildTargetList.add(Target) + + if FileType not in self._BuildTargets: + self._BuildTargets[FileType] = set() + self._BuildTargets[FileType].add(Target) + + if not Source.IsBinary and Source == File: + self._IntroBuildTargetList.add(Target) + + # to avoid cyclic rule + if FileType in RuleChain: + break + + RuleChain.append(FileType) + SourceList.extend(Target.Outputs) + LastTarget = Target + FileType = TAB_UNKNOWN_FILE + + def _GetTargets(self): + if self._BuildTargets == None: + self._IntroBuildTargetList = set() + self._FinalBuildTargetList = set() + self._BuildTargets = {} + self._FileTypes = {} + + #TRICK: call _GetSourceFileList to apply build rule for binary files + if self.SourceFileList: + pass + + #TRICK: call _GetBinaryFileList to apply build rule for binary files + if self.BinaryFileList: + pass + + return self._BuildTargets + + def _GetIntroTargetList(self): + self._GetTargets() + return self._IntroBuildTargetList + + def _GetFinalTargetList(self): + self._GetTargets() + return self._FinalBuildTargetList + + def _GetFileTypes(self): + self._GetTargets() + return self._FileTypes + + ## Get the list of package object the module depends on + # + # @retval list The package object list + # + def _GetDependentPackageList(self): + return self.Module.Packages + + ## Return the list of auto-generated code file + # + # @retval list The list of auto-generated file + # + def _GetAutoGenFileList(self): + if self._AutoGenFileList == None: + self._AutoGenFileList = {} + AutoGenC = TemplateString() + AutoGenH = TemplateString() + StringH = TemplateString() + GenC.CreateCode(self, AutoGenC, AutoGenH, StringH) + if str(AutoGenC) != "" and TAB_C_CODE_FILE in self.FileTypes: + AutoFile = PathClass(gAutoGenCodeFileName, self.DebugDir) + self._AutoGenFileList[AutoFile] = str(AutoGenC) + self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE) + if str(AutoGenH) != "": + AutoFile = PathClass(gAutoGenHeaderFileName, self.DebugDir) + self._AutoGenFileList[AutoFile] = str(AutoGenH) + self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE) + if str(StringH) != "": + AutoFile = PathClass(gAutoGenStringFileName % {"module_name":self.Name}, self.DebugDir) + self._AutoGenFileList[AutoFile] = str(StringH) + self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE) + return self._AutoGenFileList + + ## Return the list of library modules explicitly or implicityly used by this module + def _GetLibraryList(self): + if self._DependentLibraryList == None: + # only merge library classes and PCD for non-library module + if self.IsLibrary: + self._DependentLibraryList = [] + else: + if self.AutoGenVersion < 0x00010005: + self._DependentLibraryList = self.PlatformInfo.ResolveLibraryReference(self.Module) + else: + self._DependentLibraryList = self.PlatformInfo.ApplyLibraryInstance(self.Module) + return self._DependentLibraryList + + ## Get the list of PCDs from current module + # + # @retval list The list of PCD + # + def _GetModulePcdList(self): + if self._ModulePcdList == None: + # apply PCD settings from platform + self._ModulePcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, self.Module.Pcds) + return self._ModulePcdList + + ## Get the list of PCDs from dependent libraries + # + # @retval list The list of PCD + # + def _GetLibraryPcdList(self): + if self._LibraryPcdList == None: + Pcds = {} + if not self.IsLibrary: + # get PCDs from dependent libraries + for Library in self.DependentLibraryList: + for Key in Library.Pcds: + # skip duplicated PCDs + if Key in self.Module.Pcds or Key in Pcds: + continue + Pcds[Key] = copy.copy(Library.Pcds[Key]) + # apply PCD settings from platform + self._LibraryPcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, Pcds) + else: + self._LibraryPcdList = [] + return self._LibraryPcdList + + ## Get the GUID value mapping + # + # @retval dict The mapping between GUID cname and its value + # + def _GetGuidList(self): + if self._GuidList == None: + self._GuidList = self.Module.Guids + for Library in self.DependentLibraryList: + self._GuidList.update(Library.Guids) + return self._GuidList + + ## Get the protocol value mapping + # + # @retval dict The mapping between protocol cname and its value + # + def _GetProtocolList(self): + if self._ProtocolList == None: + self._ProtocolList = self.Module.Protocols + for Library in self.DependentLibraryList: + self._ProtocolList.update(Library.Protocols) + return self._ProtocolList + + ## Get the PPI value mapping + # + # @retval dict The mapping between PPI cname and its value + # + def _GetPpiList(self): + if self._PpiList == None: + self._PpiList = self.Module.Ppis + for Library in self.DependentLibraryList: + self._PpiList.update(Library.Ppis) + return self._PpiList + + ## Get the list of include search path + # + # @retval list The list path + # + def _GetIncludePathList(self): + if self._IncludePathList == None: + self._IncludePathList = [] + if self.AutoGenVersion < 0x00010005: + for Inc in self.Module.Includes: + if Inc not in self._IncludePathList: + self._IncludePathList.append(Inc) + # for r8 modules + Inc = path.join(Inc, self.Arch.capitalize()) + if os.path.exists(Inc) and Inc not in self._IncludePathList: + self._IncludePathList.append(Inc) + # r8 module needs to put DEBUG_DIR at the end of search path and not to use SOURCE_DIR all the time + self._IncludePathList.append(self.DebugDir) + else: + self._IncludePathList.append(self.MetaFile.Dir) + self._IncludePathList.append(self.DebugDir) + + for Package in self.Module.Packages: + PackageDir = path.join(self.WorkspaceDir, Package.MetaFile.Dir) + if PackageDir not in self._IncludePathList: + self._IncludePathList.append(PackageDir) + for Inc in Package.Includes: + if Inc not in self._IncludePathList: + self._IncludePathList.append(str(Inc)) + return self._IncludePathList + + ## Create makefile for the module and its dependent libraries + # + # @param CreateLibraryMakeFile Flag indicating if or not the makefiles of + # dependent libraries will be created + # + def CreateMakeFile(self, CreateLibraryMakeFile=True): + if self.IsMakeFileCreated: + return + + if not self.IsLibrary and CreateLibraryMakeFile: + for LibraryAutoGen in self.LibraryAutoGenList: + LibraryAutoGen.CreateMakeFile() + + if len(self.CustomMakefile) == 0: + Makefile = GenMake.ModuleMakefile(self) + else: + Makefile = GenMake.CustomMakefile(self) + if Makefile.Generate(): + EdkLogger.debug(EdkLogger.DEBUG_9, "Generated makefile for module %s [%s]" % + (self.Name, self.Arch)) + else: + EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for module %s [%s]" % + (self.Name, self.Arch)) + + self.IsMakeFileCreated = True + + ## Create autogen code for the module and its dependent libraries + # + # @param CreateLibraryCodeFile Flag indicating if or not the code of + # dependent libraries will be created + # + def CreateCodeFile(self, CreateLibraryCodeFile=True): + if self.IsCodeFileCreated: + return + + if not self.IsLibrary and CreateLibraryCodeFile: + for LibraryAutoGen in self.LibraryAutoGenList: + LibraryAutoGen.CreateCodeFile() + + AutoGenList = [] + IgoredAutoGenList = [] + + for File in self.AutoGenFileList: + if GenC.Generate(File.Path, self.AutoGenFileList[File]): + #Ignore R8 AutoGen.c + if self.AutoGenVersion < 0x00010005 and File.Name == 'AutoGen.c': + continue + + AutoGenList.append(str(File)) + else: + IgoredAutoGenList.append(str(File)) + + for ModuleType in self.DepexList: + if len(self.DepexList[ModuleType]) == 0: + continue + Dpx = GenDepex.DependencyExpression(self.DepexList[ModuleType], ModuleType, True) + if ModuleType == 'SMM_DRIVER': + DpxFile = gAutoGenSmmDepexFileName % {"module_name" : self.Name} + else: + DpxFile = gAutoGenDepexFileName % {"module_name" : self.Name} + + if Dpx.Generate(path.join(self.OutputDir, DpxFile)): + AutoGenList.append(str(DpxFile)) + else: + IgoredAutoGenList.append(str(DpxFile)) + + if IgoredAutoGenList == []: + EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] files for module %s [%s]" % + (" ".join(AutoGenList), self.Name, self.Arch)) + elif AutoGenList == []: + EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of [%s] files for module %s [%s]" % + (" ".join(IgoredAutoGenList), self.Name, self.Arch)) + else: + EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] (skipped %s) files for module %s [%s]" % + (" ".join(AutoGenList), " ".join(IgoredAutoGenList), self.Name, self.Arch)) + + self.IsCodeFileCreated = True + return AutoGenList + + ## Summarize the ModuleAutoGen objects of all libraries used by this module + def _GetLibraryAutoGenList(self): + if self._LibraryAutoGenList == None: + self._LibraryAutoGenList = [] + for Library in self.DependentLibraryList: + La = ModuleAutoGen( + self.Workspace, + Library.MetaFile, + self.BuildTarget, + self.ToolChain, + self.Arch, + self.PlatformInfo.MetaFile + ) + if La not in self._LibraryAutoGenList: + self._LibraryAutoGenList.append(La) + for Lib in La.CodaTargetList: + self._ApplyBuildRule(Lib.Target, TAB_UNKNOWN_FILE) + return self._LibraryAutoGenList + + ## Return build command string + # + # @retval string Build command string + # + def _GetBuildCommand(self): + return self.PlatformInfo.BuildCommand + + + Module = property(_GetModule) + Name = property(_GetBaseName) + Guid = property(_GetGuid) + Version = property(_GetVersion) + ModuleType = property(_GetModuleType) + ComponentType = property(_GetComponentType) + BuildType = property(_GetBuildType) + PcdIsDriver = property(_GetPcdIsDriver) + AutoGenVersion = property(_GetAutoGenVersion) + Macros = property(_GetMacros) + Specification = property(_GetSpecification) + + IsLibrary = property(_IsLibrary) + + BuildDir = property(_GetBuildDir) + OutputDir = property(_GetOutputDir) + DebugDir = property(_GetDebugDir) + MakeFileDir = property(_GetMakeFileDir) + CustomMakefile = property(_GetCustomMakefile) + + IncludePathList = property(_GetIncludePathList) + AutoGenFileList = property(_GetAutoGenFileList) + UnicodeFileList = property(_GetUnicodeFileList) + SourceFileList = property(_GetSourceFileList) + BinaryFileList = property(_GetBinaryFiles) # FileType : [File List] + Targets = property(_GetTargets) + IntroTargetList = property(_GetIntroTargetList) + CodaTargetList = property(_GetFinalTargetList) + FileTypes = property(_GetFileTypes) + BuildRules = property(_GetBuildRules) + + DependentPackageList = property(_GetDependentPackageList) + DependentLibraryList = property(_GetLibraryList) + LibraryAutoGenList = property(_GetLibraryAutoGenList) + DerivedPackageList = property(_GetDerivedPackageList) + + ModulePcdList = property(_GetModulePcdList) + LibraryPcdList = property(_GetLibraryPcdList) + GuidList = property(_GetGuidList) + ProtocolList = property(_GetProtocolList) + PpiList = property(_GetPpiList) + DepexList = property(_GetDepexTokenList) + BuildOption = property(_GetModuleBuildOption) + BuildCommand = property(_GetBuildCommand) + +# This acts like the main() function for the script, unless it is 'import'ed into another script. +if __name__ == '__main__': + pass + diff --git a/BaseTools/Source/Python/AutoGen/BuildEngine.py b/BaseTools/Source/Python/AutoGen/BuildEngine.py new file mode 100644 index 0000000000..cbe7d60f3f --- /dev/null +++ b/BaseTools/Source/Python/AutoGen/BuildEngine.py @@ -0,0 +1,622 @@ +## @file +# The engine for building files +# +# Copyright (c) 2007, 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 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 re +import copy +import string + +from Common.GlobalData import * +from Common.BuildToolError import * +from Common.Misc import tdict, PathClass +from Common.String import NormPath +from Common.DataType import * + +import Common.EdkLogger as EdkLogger + +## Convert file type to file list macro name +# +# @param FileType The name of file type +# +# @retval string The name of macro +# +def FileListMacro(FileType): + return "%sS" % FileType.replace("-", "_").upper() + +## Convert file type to list file macro name +# +# @param FileType The name of file type +# +# @retval string The name of macro +# +def ListFileMacro(FileType): + return "%s_LIST" % FileListMacro(FileType) + +class TargetDescBlock(object): + _Cache_ = {} # {TargetFile : TargetDescBlock object} + + # Factory method + def __new__(Class, Inputs, Outputs, Commands, Dependencies): + if Outputs[0] in Class._Cache_: + Tdb = Class._Cache_[Outputs[0]] + for File in Inputs: + Tdb.AddInput(File) + else: + Tdb = super(TargetDescBlock, Class).__new__(Class) + Tdb._Init(Inputs, Outputs, Commands, Dependencies) + #Class._Cache_[Outputs[0]] = Tdb + return Tdb + + def _Init(self, Inputs, Outputs, Commands, Dependencies): + self.Inputs = Inputs + self.Outputs = Outputs + self.Commands = Commands + self.Dependencies = Dependencies + if self.Outputs: + self.Target = self.Outputs[0] + else: + self.Target = None + + def __str__(self): + return self.Target.Path + + def __hash__(self): + return hash(self.Target.Path) + + def __eq__(self, Other): + if type(Other) == type(self): + return Other.Target.Path == self.Target.Path + else: + return str(Other) == self.Target.Path + + def AddInput(self, Input): + if Input not in self.Inputs: + self.Inputs.append(Input) + + def IsMultipleInput(self): + return len(self.Inputs) > 1 + + @staticmethod + def Renew(): + TargetDescBlock._Cache_ = {} + +## Class for one build rule +# +# This represents a build rule which can give out corresponding command list for +# building the given source file(s). The result can be used for generating the +# target for makefile. +# +class FileBuildRule: + INC_LIST_MACRO = "INC_LIST" + INC_MACRO = "INC" + + ## constructor + # + # @param Input The dictionary represeting input file(s) for a rule + # @param Output The list represeting output file(s) for a rule + # @param Command The list containing commands to generate the output from input + # + def __init__(self, Type, Input, Output, Command, ExtraDependency=None): + # The Input should not be empty + if not Input: + Input = [] + if not Output: + Output = [] + if not Command: + Command = [] + + self.FileListMacro = FileListMacro(Type) + self.ListFileMacro = ListFileMacro(Type) + self.IncListFileMacro = self.INC_LIST_MACRO + + self.SourceFileType = Type + # source files listed not in "*" or "?" pattern format + if not ExtraDependency: + self.ExtraSourceFileList = [] + else: + self.ExtraSourceFileList = ExtraDependency + + # + # Search macros used in command lines for _LIST and INC_LIST. + # If found, generate a file to keep the input files used to get over the + # limitation of command line length + # + self.MacroList = [] + self.CommandList = [] + for CmdLine in Command: + self.MacroList.extend(gMacroPattern.findall(CmdLine)) + # replace path separator with native one + self.CommandList.append(CmdLine) + + # Indicate what should be generated + if self.FileListMacro in self.MacroList: + self.GenFileListMacro = True + else: + self.GenFileListMacro = False + + if self.ListFileMacro in self.MacroList: + self.GenListFile = True + self.GenFileListMacro = True + else: + self.GenListFile = False + + if self.INC_LIST_MACRO in self.MacroList: + self.GenIncListFile = True + else: + self.GenIncListFile = False + + # Check input files + self.IsMultipleInput = False + self.SourceFileExtList = [] + for File in Input: + Base, Ext = os.path.splitext(File) + if Base.find("*") >= 0: + # There's "*" in the file name + self.IsMultipleInput = True + self.GenFileListMacro = True + elif Base.find("?") < 0: + # There's no "*" and "?" in file name + self.ExtraSourceFileList.append(File) + continue + if Ext not in self.SourceFileExtList: + self.SourceFileExtList.append(Ext) + + # Check output files + self.DestFileList = [] + for File in Output: + self.DestFileList.append(File) + + # All build targets generated by this rule for a module + self.BuildTargets = {} + + ## str() function support + # + # @retval string + # + def __str__(self): + SourceString = "" + SourceString += " %s %s %s" % (self.SourceFileType, " ".join(self.SourceFileExtList), self.ExtraSourceFileList) + DestString = ", ".join(self.DestFileList) + CommandString = "\n\t".join(self.CommandList) + return "%s : %s\n\t%s" % (DestString, SourceString, CommandString) + + ## Check if given file extension is supported by this rule + # + # @param FileExt The extension of a file + # + # @retval True If the extension is supported + # @retval False If the extension is not supported + # + def IsSupported(self, FileExt): + return FileExt in self.SourceFileExtList + + def Instantiate(self, Macros={}): + NewRuleObject = copy.copy(self) + NewRuleObject.BuildTargets = {} + NewRuleObject.DestFileList = [] + for File in self.DestFileList: + NewRuleObject.DestFileList.append(PathClass(NormPath(File, Macros))) + return NewRuleObject + + ## Apply the rule to given source file(s) + # + # @param SourceFile One file or a list of files to be built + # @param RelativeToDir The relative path of the source file + # @param PathSeparator Path separator + # + # @retval tuple (Source file in full path, List of individual sourcefiles, Destionation file, List of build commands) + # + def Apply(self, SourceFile): + if not self.CommandList or not self.DestFileList: + return None + + # source file + if self.IsMultipleInput: + SrcFileName = "" + SrcFileBase = "" + SrcFileExt = "" + SrcFileDir = "" + SrcPath = "" + # SourceFile must be a list + SrcFile = "$(%s)" % self.FileListMacro + else: + SrcFileName, SrcFileBase, SrcFileExt = SourceFile.Name, SourceFile.BaseName, SourceFile.Ext + if SourceFile.Root: + SrcFileDir = SourceFile.SubDir + if SrcFileDir == "": + SrcFileDir = "." + else: + SrcFileDir = "." + SrcFile = SourceFile.Path + SrcPath = SourceFile.Dir + + # destination file (the first one) + if self.DestFileList: + DestFile = self.DestFileList[0].Path + DestPath = self.DestFileList[0].Dir + DestFileName = self.DestFileList[0].Name + DestFileBase, DestFileExt = self.DestFileList[0].BaseName, self.DestFileList[0].Ext + else: + DestFile = "" + DestPath = "" + DestFileName = "" + DestFileBase = "" + DestFileExt = "" + + BuildRulePlaceholderDict = { + # source file + "src" : SrcFile, + "s_path" : SrcPath, + "s_dir" : SrcFileDir, + "s_name" : SrcFileName, + "s_base" : SrcFileBase, + "s_ext" : SrcFileExt, + # destination file + "dst" : DestFile, + "d_path" : DestPath, + "d_name" : DestFileName, + "d_base" : DestFileBase, + "d_ext" : DestFileExt, + } + + DstFile = [] + for File in self.DestFileList: + File = string.Template(str(File)).safe_substitute(BuildRulePlaceholderDict) + File = string.Template(str(File)).safe_substitute(BuildRulePlaceholderDict) + DstFile.append(PathClass(File, IsBinary=True)) + + if DstFile[0] in self.BuildTargets: + TargetDesc = self.BuildTargets[DstFile[0]] + TargetDesc.AddInput(SourceFile) + else: + CommandList = [] + for CommandString in self.CommandList: + CommandString = string.Template(CommandString).safe_substitute(BuildRulePlaceholderDict) + CommandString = string.Template(CommandString).safe_substitute(BuildRulePlaceholderDict) + CommandList.append(CommandString) + TargetDesc = TargetDescBlock([SourceFile], DstFile, CommandList, self.ExtraSourceFileList) + TargetDesc.ListFileMacro = self.ListFileMacro + TargetDesc.FileListMacro = self.FileListMacro + TargetDesc.IncListFileMacro = self.IncListFileMacro + TargetDesc.GenFileListMacro = self.GenFileListMacro + TargetDesc.GenListFile = self.GenListFile + TargetDesc.GenIncListFile = self.GenIncListFile + self.BuildTargets[DstFile[0]] = TargetDesc + return TargetDesc + +## Class for build rules +# +# BuildRule class parses rules defined in a file or passed by caller, and converts +# the rule into FileBuildRule object. +# +class BuildRule: + _SectionHeader = "SECTIONHEADER" + _Section = "SECTION" + _SubSectionHeader = "SUBSECTIONHEADER" + _SubSection = "SUBSECTION" + _InputFile = "INPUTFILE" + _OutputFile = "OUTPUTFILE" + _ExtraDependency = "EXTRADEPENDENCY" + _Command = "COMMAND" + _UnknownSection = "UNKNOWNSECTION" + + _SubSectionList = [_InputFile, _OutputFile, _Command] + + _PATH_SEP = "(+)" + _FileTypePattern = re.compile("^[_a-zA-Z][_\-0-9a-zA-Z]*$") + _BinaryFileRule = FileBuildRule(TAB_DEFAULT_BINARY_FILE, [], [os.path.join("$(OUTPUT_DIR)", "${s_name}")], + ["$(CP) ${src} ${dst}"], []) + + ## Constructor + # + # @param File The file containing build rules in a well defined format + # @param Content The string list of build rules in a well defined format + # @param LineIndex The line number from which the parsing will begin + # @param SupportedFamily The list of supported tool chain families + # + def __init__(self, File=None, Content=None, LineIndex=0, SupportedFamily=["MSFT", "INTEL", "GCC", "RVCT"]): + self.RuleFile = File + # Read build rules from file if it's not none + if File != None: + try: + self.RuleContent = open(File, 'r').readlines() + except: + EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=File) + elif Content != None: + self.RuleContent = Content + else: + EdkLogger.error("build", PARAMETER_MISSING, ExtraData="No rule file or string given") + + self.SupportedToolChainFamilyList = SupportedFamily + self.RuleDatabase = tdict(True, 4) # {FileExt, ModuleType, Arch, Family : FileBuildRule object} + self.Ext2FileType = {} # {ext : file-type} + self.FileTypeList = set() + + self._LineIndex = LineIndex + self._State = "" + self._RuleInfo = tdict(True, 2) # {toolchain family : {"InputFile": {}, "OutputFile" : [], "Command" : []}} + self._FileType = '' + self._BuildTypeList = [] + self._ArchList = [] + self._FamilyList = [] + self._TotalToolChainFamilySet = set() + self._RuleObjectList = [] # FileBuildRule object list + + self.Parse() + + # some intrinsic rules + self.RuleDatabase[TAB_DEFAULT_BINARY_FILE, "COMMON", "COMMON", "COMMON"] = self._BinaryFileRule + self.FileTypeList.add(TAB_DEFAULT_BINARY_FILE) + + ## Parse the build rule strings + def Parse(self): + self._State = self._Section + for Index in range(self._LineIndex, len(self.RuleContent)): + # Clean up the line and replace path separator with native one + Line = self.RuleContent[Index].strip().replace(self._PATH_SEP, os.path.sep) + self.RuleContent[Index] = Line + + # skip empty or comment line + if Line == "" or Line[0] == "#": + continue + + # find out section header, enclosed by [] + if Line[0] == '[' and Line[-1] == ']': + # merge last section information into rule database + self.EndOfSection() + self._State = self._SectionHeader + # find out sub-section header, enclosed by <> + elif Line[0] == '<' and Line[-1] == '>': + if self._State != self._UnknownSection: + self._State = self._SubSectionHeader + + # call section handler to parse each (sub)section + self._StateHandler[self._State](self, Index) + # merge last section information into rule database + self.EndOfSection() + + ## Parse definitions under a section + # + # @param LineIndex The line index of build rule text + # + def ParseSection(self, LineIndex): + pass + + ## Parse definitions under a subsection + # + # @param LineIndex The line index of build rule text + # + def ParseSubSection(self, LineIndex): + # currenly nothing here + pass + + ## Placeholder for not supported sections + # + # @param LineIndex The line index of build rule text + # + def SkipSection(self, LineIndex): + pass + + ## Merge section information just got into rule database + def EndOfSection(self): + Database = self.RuleDatabase + # if there's specific toochain family, 'COMMON' doesn't make sense any more + if len(self._TotalToolChainFamilySet) > 1 and 'COMMON' in self._TotalToolChainFamilySet: + self._TotalToolChainFamilySet.remove('COMMON') + for Family in self._TotalToolChainFamilySet: + Input = self._RuleInfo[Family, self._InputFile] + Output = self._RuleInfo[Family, self._OutputFile] + Command = self._RuleInfo[Family, self._Command] + ExtraDependency = self._RuleInfo[Family, self._ExtraDependency] + + BuildRule = FileBuildRule(self._FileType, Input, Output, Command, ExtraDependency) + for BuildType in self._BuildTypeList: + for Arch in self._ArchList: + Database[self._FileType, BuildType, Arch, Family] = BuildRule + for FileExt in BuildRule.SourceFileExtList: + self.Ext2FileType[FileExt] = self._FileType + + ## Parse section header + # + # @param LineIndex The line index of build rule text + # + def ParseSectionHeader(self, LineIndex): + self._RuleInfo = tdict(True, 2) + self._BuildTypeList = [] + self._ArchList = [] + self._FamilyList = [] + self._TotalToolChainFamilySet = set() + FileType = '' + RuleNameList = self.RuleContent[LineIndex][1:-1].split(',') + for RuleName in RuleNameList: + Arch = 'COMMON' + BuildType = 'COMMON' + TokenList = [Token.strip().upper() for Token in RuleName.split('.')] + # old format: Build.File-Type + if TokenList[0] == "BUILD": + if len(TokenList) == 1: + EdkLogger.error("build", FORMAT_INVALID, "Invalid rule section", + File=self.RuleFile, Line=LineIndex+1, + ExtraData=self.RuleContent[LineIndex]) + + FileType = TokenList[1] + if FileType == '': + EdkLogger.error("build", FORMAT_INVALID, "No file type given", + File=self.RuleFile, Line=LineIndex+1, + ExtraData=self.RuleContent[LineIndex]) + if self._FileTypePattern.match(FileType) == None: + EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1, + ExtraData="Only character, number (non-first character), '_' and '-' are allowed in file type") + # new format: File-Type.Build-Type.Arch + else: + if FileType == '': + FileType = TokenList[0] + elif FileType != TokenList[0]: + EdkLogger.error("build", FORMAT_INVALID, + "Different file types are not allowed in the same rule section", + File=self.RuleFile, Line=LineIndex+1, + ExtraData=self.RuleContent[LineIndex]) + if len(TokenList) > 1: + BuildType = TokenList[1] + if len(TokenList) > 2: + Arch = TokenList[2] + if BuildType not in self._BuildTypeList: + self._BuildTypeList.append(BuildType) + if Arch not in self._ArchList: + self._ArchList.append(Arch) + + if 'COMMON' in self._BuildTypeList and len(self._BuildTypeList) > 1: + EdkLogger.error("build", FORMAT_INVALID, + "Specific build types must not be mixed with common one", + File=self.RuleFile, Line=LineIndex+1, + ExtraData=self.RuleContent[LineIndex]) + if 'COMMON' in self._ArchList and len(self._ArchList) > 1: + EdkLogger.error("build", FORMAT_INVALID, + "Specific ARCH must not be mixed with common one", + File=self.RuleFile, Line=LineIndex+1, + ExtraData=self.RuleContent[LineIndex]) + + self._FileType = FileType + self._State = self._Section + self.FileTypeList.add(FileType) + + ## Parse sub-section header + # + # @param LineIndex The line index of build rule text + # + def ParseSubSectionHeader(self, LineIndex): + SectionType = "" + List = self.RuleContent[LineIndex][1:-1].split(',') + FamilyList = [] + for Section in List: + TokenList = Section.split('.') + Type = TokenList[0].strip().upper() + + if SectionType == "": + SectionType = Type + elif SectionType != Type: + EdkLogger.error("build", FORMAT_INVALID, + "Two different section types are not allowed in the same sub-section", + File=self.RuleFile, Line=LineIndex+1, + ExtraData=self.RuleContent[LineIndex]) + + if len(TokenList) > 1: + Family = TokenList[1].strip().upper() + else: + Family = "COMMON" + + if Family not in FamilyList: + FamilyList.append(Family) + + self._FamilyList = FamilyList + self._TotalToolChainFamilySet.update(FamilyList) + self._State = SectionType.upper() + if 'COMMON' in FamilyList and len(FamilyList) > 1: + EdkLogger.error("build", FORMAT_INVALID, + "Specific tool chain family should not be mixed with general one", + File=self.RuleFile, Line=LineIndex+1, + ExtraData=self.RuleContent[LineIndex]) + if self._State not in self._StateHandler: + EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex+1, + ExtraData="Unknown subsection: %s" % self.RuleContent[LineIndex]) + ## Parse sub-section + # + # @param LineIndex The line index of build rule text + # + def ParseInputFile(self, LineIndex): + FileList = [File.strip() for File in self.RuleContent[LineIndex].split(",")] + for ToolChainFamily in self._FamilyList: + InputFiles = self._RuleInfo[ToolChainFamily, self._State] + if InputFiles == None: + InputFiles = [] + self._RuleInfo[ToolChainFamily, self._State] = InputFiles + InputFiles.extend(FileList) + + ## Parse sub-section + # + # @param LineIndex The line index of build rule text + # + def ParseCommon(self, LineIndex): + for ToolChainFamily in self._FamilyList: + Items = self._RuleInfo[ToolChainFamily, self._State] + if Items == None: + Items = [] + self._RuleInfo[ToolChainFamily, self._State] = Items + Items.append(self.RuleContent[LineIndex]) + + ## Get a build rule via [] operator + # + # @param FileExt The extension of a file + # @param ToolChainFamily The tool chain family name + # @param BuildVersion The build version number. "*" means any rule + # is applicalbe. + # + # @retval FileType The file type string + # @retval FileBuildRule The object of FileBuildRule + # + # Key = (FileExt, ModuleType, Arch, ToolChainFamily) + def __getitem__(self, Key): + if not Key: + return None + + if Key[0] in self.Ext2FileType: + Type = self.Ext2FileType[Key[0]] + elif Key[0].upper() in self.FileTypeList: + Type = Key[0].upper() + else: + return None + + if len(Key) > 1: + Key = (Type,) + Key[1:] + else: + Key = (Type,) + return self.RuleDatabase[Key] + + _StateHandler = { + _SectionHeader : ParseSectionHeader, + _Section : ParseSection, + _SubSectionHeader : ParseSubSectionHeader, + _SubSection : ParseSubSection, + _InputFile : ParseInputFile, + _OutputFile : ParseCommon, + _ExtraDependency : ParseCommon, + _Command : ParseCommon, + _UnknownSection : SkipSection, + } + +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +if __name__ == '__main__': + import sys + EdkLogger.Initialize() + if len(sys.argv) > 1: + Br = BuildRule(sys.argv[1]) + print str(Br[".c", "DXE_DRIVER", "IA32", "MSFT"][1]) + print + print str(Br[".c", "DXE_DRIVER", "IA32", "INTEL"][1]) + print + print str(Br[".c", "DXE_DRIVER", "IA32", "GCC"][1]) + print + print str(Br[".ac", "ACPI_TABLE", "IA32", "MSFT"][1]) + print + print str(Br[".h", "ACPI_TABLE", "IA32", "INTEL"][1]) + print + print str(Br[".ac", "ACPI_TABLE", "IA32", "MSFT"][1]) + print + print str(Br[".s", "SEC", "IPF", "COMMON"][1]) + print + print str(Br[".s", "SEC"][1]) + diff --git a/BaseTools/Source/Python/AutoGen/GenC.py b/BaseTools/Source/Python/AutoGen/GenC.py new file mode 100644 index 0000000000..b62a12708b --- /dev/null +++ b/BaseTools/Source/Python/AutoGen/GenC.py @@ -0,0 +1,1931 @@ +## @file +# Routines for generating AutoGen.h and AutoGen.c +# +# Copyright (c) 2007, 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 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 string + +from Common import EdkLogger + +from Common.BuildToolError import * +from Common.DataType import * +from Common.Misc import * +from Common.String import StringToArray +from StrGather import * + +## PCD type string +gItemTypeStringDatabase = { + TAB_PCDS_FEATURE_FLAG : 'FixedAtBuild', + TAB_PCDS_FIXED_AT_BUILD : 'FixedAtBuild', + TAB_PCDS_PATCHABLE_IN_MODULE: 'BinaryPatch', + TAB_PCDS_DYNAMIC : '', + TAB_PCDS_DYNAMIC_DEFAULT : '', + TAB_PCDS_DYNAMIC_VPD : '', + TAB_PCDS_DYNAMIC_HII : '', + TAB_PCDS_DYNAMIC_EX : '', + TAB_PCDS_DYNAMIC_EX_DEFAULT : '', + TAB_PCDS_DYNAMIC_EX_VPD : '', + TAB_PCDS_DYNAMIC_EX_HII : '', +} + +## Dynamic PCD types +gDynamicPcd = [TAB_PCDS_DYNAMIC, TAB_PCDS_DYNAMIC_DEFAULT, TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_HII] + +## Dynamic-ex PCD types +gDynamicExPcd = [TAB_PCDS_DYNAMIC_EX, TAB_PCDS_DYNAMIC_EX_DEFAULT, TAB_PCDS_DYNAMIC_EX_VPD, TAB_PCDS_DYNAMIC_EX_HII] + +## Datum size +gDatumSizeStringDatabase = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64','BOOLEAN':'BOOLEAN','VOID*':'8'} +gDatumSizeStringDatabaseH = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64','BOOLEAN':'BOOL','VOID*':'PTR'} +gDatumSizeStringDatabaseLib = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64','BOOLEAN':'Bool','VOID*':'Ptr'} + +## Mapping between PCD driver type and EFI phase +gPcdPhaseMap = { + "PEI_PCD_DRIVER" : "PEI", + "DXE_PCD_DRIVER" : "DXE" +} + +gPcdDatabaseCommonAutoGenH = """ +// +// The following definition will be generated by build tool +// + +// +// Common definitions +// +typedef UINT8 SKU_ID; + +#define PCD_TYPE_SHIFT 28 + +#define PCD_TYPE_DATA (0x0 << PCD_TYPE_SHIFT) +#define PCD_TYPE_HII (0x8 << PCD_TYPE_SHIFT) +#define PCD_TYPE_VPD (0x4 << PCD_TYPE_SHIFT) +#define PCD_TYPE_SKU_ENABLED (0x2 << PCD_TYPE_SHIFT) +#define PCD_TYPE_STRING (0x1 << PCD_TYPE_SHIFT) + +#define PCD_TYPE_ALL_SET (PCD_TYPE_DATA | PCD_TYPE_HII | PCD_TYPE_VPD | PCD_TYPE_SKU_ENABLED | PCD_TYPE_STRING) + +#define PCD_DATUM_TYPE_SHIFT 24 + +#define PCD_DATUM_TYPE_POINTER (0x0 << PCD_DATUM_TYPE_SHIFT) +#define PCD_DATUM_TYPE_UINT8 (0x1 << PCD_DATUM_TYPE_SHIFT) +#define PCD_DATUM_TYPE_UINT16 (0x2 << PCD_DATUM_TYPE_SHIFT) +#define PCD_DATUM_TYPE_UINT32 (0x4 << PCD_DATUM_TYPE_SHIFT) +#define PCD_DATUM_TYPE_UINT64 (0x8 << PCD_DATUM_TYPE_SHIFT) + +#define PCD_DATUM_TYPE_ALL_SET (PCD_DATUM_TYPE_POINTER | \\ + PCD_DATUM_TYPE_UINT8 | \\ + PCD_DATUM_TYPE_UINT16 | \\ + PCD_DATUM_TYPE_UINT32 | \\ + PCD_DATUM_TYPE_UINT64) + +#define PCD_DATABASE_OFFSET_MASK (~(PCD_TYPE_ALL_SET | PCD_DATUM_TYPE_ALL_SET)) + +typedef struct { + UINT32 ExTokenNumber; + UINT16 LocalTokenNumber; // PCD Number of this particular platform build + UINT16 ExGuidIndex; // Index of GuidTable +} DYNAMICEX_MAPPING; + +typedef struct { + UINT32 SkuDataStartOffset; //We have to use offsetof MACRO as we don't know padding done by compiler + UINT32 SkuIdTableOffset; //Offset from the PCD_DB +} SKU_HEAD; + +typedef struct { + UINT16 GuidTableIndex; // Offset in Guid Table in units of GUID. + UINT16 StringIndex; // Offset in String Table in units of UINT16. + UINT16 Offset; // Offset in Variable + UINT16 DefaultValueOffset; // Offset of the Default Value +} VARIABLE_HEAD; + +typedef struct { + UINT32 Offset; +} VPD_HEAD; + +typedef UINT16 STRING_HEAD; + +typedef UINT16 SIZE_INFO; + +#define offsetof(s,m) (UINT32) (UINTN) &(((s *)0)->m) + +""" + +gPcdDatabaseEpilogueAutoGenH = """ +typedef struct { + PEI_PCD_DATABASE PeiDb; + DXE_PCD_DATABASE DxeDb; +} PCD_DATABASE; + +#define PCD_TOTAL_TOKEN_NUMBER (PEI_LOCAL_TOKEN_NUMBER + DXE_LOCAL_TOKEN_NUMBER) + +""" + +gPcdDatabaseAutoGenH = TemplateString(""" +#define ${PHASE}_GUID_TABLE_SIZE ${GUID_TABLE_SIZE} +#define ${PHASE}_STRING_TABLE_SIZE ${STRING_TABLE_SIZE} +#define ${PHASE}_SKUID_TABLE_SIZE ${SKUID_TABLE_SIZE} +#define ${PHASE}_LOCAL_TOKEN_NUMBER_TABLE_SIZE ${LOCAL_TOKEN_NUMBER_TABLE_SIZE} +#define ${PHASE}_LOCAL_TOKEN_NUMBER ${LOCAL_TOKEN_NUMBER} +#define ${PHASE}_EXMAPPING_TABLE_SIZE ${EXMAPPING_TABLE_SIZE} +#define ${PHASE}_EX_TOKEN_NUMBER ${EX_TOKEN_NUMBER} +#define ${PHASE}_SIZE_TABLE_SIZE ${SIZE_TABLE_SIZE} +#define ${PHASE}_GUID_TABLE_EMPTY ${GUID_TABLE_EMPTY} +#define ${PHASE}_STRING_TABLE_EMPTY ${STRING_TABLE_EMPTY} +#define ${PHASE}_SKUID_TABLE_EMPTY ${SKUID_TABLE_EMPTY} +#define ${PHASE}_DATABASE_EMPTY ${DATABASE_EMPTY} +#define ${PHASE}_EXMAP_TABLE_EMPTY ${EXMAP_TABLE_EMPTY} + +typedef struct { +${BEGIN} UINT64 ${INIT_CNAME_DECL_UINT64}_${INIT_GUID_DECL_UINT64}[${INIT_NUMSKUS_DECL_UINT64}]; +${END} +${BEGIN} UINT64 ${VARDEF_CNAME_UINT64}_${VARDEF_GUID_UINT64}_VariableDefault_${VARDEF_SKUID_UINT64}; +${END} +${BEGIN} UINT32 ${INIT_CNAME_DECL_UINT32}_${INIT_GUID_DECL_UINT32}[${INIT_NUMSKUS_DECL_UINT32}]; +${END} +${BEGIN} UINT32 ${VARDEF_CNAME_UINT32}_${VARDEF_GUID_UINT32}_VariableDefault_${VARDEF_SKUID_UINT32}; +${END} +${BEGIN} VPD_HEAD ${VPD_HEAD_CNAME_DECL}_${VPD_HEAD_GUID_DECL}[${VPD_HEAD_NUMSKUS_DECL}]; +${END} + DYNAMICEX_MAPPING ExMapTable[${PHASE}_EXMAPPING_TABLE_SIZE]; + UINT32 LocalTokenNumberTable[${PHASE}_LOCAL_TOKEN_NUMBER_TABLE_SIZE]; + GUID GuidTable[${PHASE}_GUID_TABLE_SIZE]; +${BEGIN} STRING_HEAD ${STRING_HEAD_CNAME_DECL}_${STRING_HEAD_GUID_DECL}[${STRING_HEAD_NUMSKUS_DECL}]; +${END} +${BEGIN} VARIABLE_HEAD ${VARIABLE_HEAD_CNAME_DECL}_${VARIABLE_HEAD_GUID_DECL}[${VARIABLE_HEAD_NUMSKUS_DECL}]; +${END} +${BEGIN} UINT8 StringTable${STRING_TABLE_INDEX}[${STRING_TABLE_LENGTH}]; /* ${STRING_TABLE_CNAME}_${STRING_TABLE_GUID} */ +${END} + SIZE_INFO SizeTable[${PHASE}_SIZE_TABLE_SIZE]; +${BEGIN} UINT16 ${INIT_CNAME_DECL_UINT16}_${INIT_GUID_DECL_UINT16}[${INIT_NUMSKUS_DECL_UINT16}]; +${END} +${BEGIN} UINT16 ${VARDEF_CNAME_UINT16}_${VARDEF_GUID_UINT16}_VariableDefault_${VARDEF_SKUID_UINT16}; +${END} +${BEGIN} UINT8 ${INIT_CNAME_DECL_UINT8}_${INIT_GUID_DECL_UINT8}[${INIT_NUMSKUS_DECL_UINT8}]; +${END} +${BEGIN} UINT8 ${VARDEF_CNAME_UINT8}_${VARDEF_GUID_UINT8}_VariableDefault_${VARDEF_SKUID_UINT8}; +${END} +${BEGIN} BOOLEAN ${INIT_CNAME_DECL_BOOLEAN}_${INIT_GUID_DECL_BOOLEAN}[${INIT_NUMSKUS_DECL_BOOLEAN}]; +${END} +${BEGIN} BOOLEAN ${VARDEF_CNAME_BOOLEAN}_${VARDEF_GUID_BOOLEAN}_VariableDefault_${VARDEF_SKUID_BOOLEAN}; +${END} + UINT8 SkuIdTable[${PHASE}_SKUID_TABLE_SIZE]; +${SYSTEM_SKU_ID} +} ${PHASE}_PCD_DATABASE_INIT; + +typedef struct { +${PCD_DATABASE_UNINIT_EMPTY} +${BEGIN} UINT64 ${UNINIT_CNAME_DECL_UINT64}_${UNINIT_GUID_DECL_UINT64}[${UNINIT_NUMSKUS_DECL_UINT64}]; +${END} +${BEGIN} UINT32 ${UNINIT_CNAME_DECL_UINT32}_${UNINIT_GUID_DECL_UINT32}[${UNINIT_NUMSKUS_DECL_UINT32}]; +${END} +${BEGIN} UINT16 ${UNINIT_CNAME_DECL_UINT16}_${UNINIT_GUID_DECL_UINT16}[${UNINIT_NUMSKUS_DECL_UINT16}]; +${END} +${BEGIN} UINT8 ${UNINIT_CNAME_DECL_UINT8}_${UNINIT_GUID_DECL_UINT8}[${UNINIT_NUMSKUS_DECL_UINT8}]; +${END} +${BEGIN} BOOLEAN ${UNINIT_CNAME_DECL_BOOLEAN}_${UNINIT_GUID_DECL_BOOLEAN}[${UNINIT_NUMSKUS_DECL_BOOLEAN}]; +${END} +} ${PHASE}_PCD_DATABASE_UNINIT; + +#define PCD_${PHASE}_SERVICE_DRIVER_VERSION 2 + +typedef struct { + ${PHASE}_PCD_DATABASE_INIT Init; + ${PHASE}_PCD_DATABASE_UNINIT Uninit; +} ${PHASE}_PCD_DATABASE; + +#define ${PHASE}_NEX_TOKEN_NUMBER (${PHASE}_LOCAL_TOKEN_NUMBER - ${PHASE}_EX_TOKEN_NUMBER) +""") + +gEmptyPcdDatabaseAutoGenC = TemplateString(""" +${PHASE}_PCD_DATABASE_INIT g${PHASE}PcdDbInit = { + /* ExMapTable */ + { + {0, 0, 0} + }, + /* LocalTokenNumberTable */ + { + 0 + }, + /* GuidTable */ + { + {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}} + }, + /* StringTable */ + { 0 }, + /* SizeTable */ + { + 0, 0 + }, + /* SkuIdTable */ + { 0 }, + ${SYSTEM_SKU_ID_VALUE} +}; +""") + +gPcdDatabaseAutoGenC = TemplateString(""" +${PHASE}_PCD_DATABASE_INIT g${PHASE}PcdDbInit = { +${BEGIN} { ${INIT_VALUE_UINT64} }, /* ${INIT_CNAME_DECL_UINT64}_${INIT_GUID_DECL_UINT64}[${INIT_NUMSKUS_DECL_UINT64}] */ +${END} +${BEGIN} ${VARDEF_VALUE_UINT64}, /* ${VARDEF_CNAME_UINT64}_${VARDEF_GUID_UINT64}_VariableDefault_${VARDEF_SKUID_UINT64} */ +${END} +${BEGIN} { ${INIT_VALUE_UINT32} }, /* ${INIT_CNAME_DECL_UINT32}_${INIT_GUID_DECL_UINT32}[${INIT_NUMSKUS_DECL_UINT32}] */ +${END} +${BEGIN} ${VARDEF_VALUE_UINT32}, /* ${VARDEF_CNAME_UINT32}_${VARDEF_GUID_UINT32}_VariableDefault_${VARDEF_SKUID_UINT32} */ +${END} + /* VPD */ +${BEGIN} { ${VPD_HEAD_VALUE} }, /* ${VPD_HEAD_CNAME_DECL}_${VPD_HEAD_GUID_DECL}[${VPD_HEAD_NUMSKUS_DECL}] */ +${END} + /* ExMapTable */ + { +${BEGIN} { ${EXMAPPING_TABLE_EXTOKEN}, ${EXMAPPING_TABLE_LOCAL_TOKEN}, ${EXMAPPING_TABLE_GUID_INDEX} }, +${END} + }, + /* LocalTokenNumberTable */ + { +${BEGIN} offsetof(${PHASE}_PCD_DATABASE, ${TOKEN_INIT}.${TOKEN_CNAME}_${TOKEN_GUID}) | ${TOKEN_TYPE}, +${END} + }, + /* GuidTable */ + { +${BEGIN} ${GUID_STRUCTURE}, +${END} + }, +${BEGIN} { ${STRING_HEAD_VALUE} }, /* ${STRING_HEAD_CNAME_DECL}_${STRING_HEAD_GUID_DECL}[${STRING_HEAD_NUMSKUS_DECL}] */ +${END} +${BEGIN} /* ${VARIABLE_HEAD_CNAME_DECL}_${VARIABLE_HEAD_GUID_DECL}[${VARIABLE_HEAD_NUMSKUS_DECL}] */ + { + ${VARIABLE_HEAD_VALUE} + }, +${END} + /* StringTable */ +${BEGIN} ${STRING_TABLE_VALUE}, /* ${STRING_TABLE_CNAME}_${STRING_TABLE_GUID} */ +${END} + /* SizeTable */ + { +${BEGIN} ${SIZE_TABLE_MAXIMUM_LENGTH}, ${SIZE_TABLE_CURRENT_LENGTH}, /* ${SIZE_TABLE_CNAME}_${SIZE_TABLE_GUID} */ +${END} + }, +${BEGIN} { ${INIT_VALUE_UINT16} }, /* ${INIT_CNAME_DECL_UINT16}_${INIT_GUID_DECL_UINT16}[${INIT_NUMSKUS_DECL_UINT16}] */ +${END} +${BEGIN} ${VARDEF_VALUE_UINT16}, /* ${VARDEF_CNAME_UINT16}_${VARDEF_GUID_UINT16}_VariableDefault_${VARDEF_SKUID_UINT16} */ +${END} +${BEGIN} { ${INIT_VALUE_UINT8} }, /* ${INIT_CNAME_DECL_UINT8}_${INIT_GUID_DECL_UINT8}[${INIT_NUMSKUS_DECL_UINT8}] */ +${END} +${BEGIN} ${VARDEF_VALUE_UINT8}, /* ${VARDEF_CNAME_UINT8}_${VARDEF_GUID_UINT8}_VariableDefault_${VARDEF_SKUID_UINT8} */ +${END} +${BEGIN} { ${INIT_VALUE_BOOLEAN} }, /* ${INIT_CNAME_DECL_BOOLEAN}_${INIT_GUID_DECL_BOOLEAN}[${INIT_NUMSKUS_DECL_BOOLEAN}] */ +${END} +${BEGIN} ${VARDEF_VALUE_BOOLEAN}, /* ${VARDEF_CNAME_BOOLEAN}_${VARDEF_GUID_BOOLEAN}_VariableDefault_${VARDEF_SKUID_BOOLEAN} */ +${END} + /* SkuIdTable */ + { ${BEGIN}${SKUID_VALUE}, ${END} }, + ${SYSTEM_SKU_ID_VALUE} +}; +""") + + +## AutoGen File Header Templates +gAutoGenHeaderString = TemplateString("""\ +/** + DO NOT EDIT + FILE auto-generated + Module name: + ${FileName} + Abstract: Auto-generated ${FileName} for building module or library. +**/ +""") + +gAutoGenHPrologueString = TemplateString(""" +#ifndef _${File}_${Guid} +#define _${File}_${Guid} + +""") + +gAutoGenHEpilogueString = """ +#endif +""" + +## PEI Core Entry Point Templates +gPeiCoreEntryPointPrototype = TemplateString(""" +${BEGIN} +VOID +EFIAPI +${Function} ( + IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, + IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList, + IN VOID *Context + ); +${END} +""") + +gPeiCoreEntryPointString = TemplateString(""" +${BEGIN} +VOID +EFIAPI +ProcessModuleEntryPointList ( + IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, + IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList, + IN VOID *Context + ) + +{ + ${Function} (SecCoreData, PpiList, Context); +} +${END} +""") + + +## DXE Core Entry Point Templates +gDxeCoreEntryPointPrototype = TemplateString(""" +${BEGIN} +VOID +EFIAPI +${Function} ( + IN VOID *HobStart + ); +${END} +""") + +gDxeCoreEntryPointString = TemplateString(""" +${BEGIN} +VOID +EFIAPI +ProcessModuleEntryPointList ( + IN VOID *HobStart + ) + +{ + ${Function} (HobStart); +} +${END} +""") + +## PEIM Entry Point Templates +gPeimEntryPointPrototype = TemplateString(""" +${BEGIN} +EFI_STATUS +EFIAPI +${Function} ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ); +${END} +""") + +## SMM_CORE Entry Point Templates +gSmmCoreEntryPointString = TemplateString(""" +const UINT32 _gUefiDriverRevision = 0; +${BEGIN} +EFI_STATUS +${Function} ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +EFI_STATUS +EFIAPI +ProcessModuleEntryPointList ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + return ${Function} (ImageHandle, SystemTable); +} +${END} +""") + +gPeimEntryPointString = [ +TemplateString(""" +GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = ${PiSpecVersion}; + +EFI_STATUS +EFIAPI +ProcessModuleEntryPointList ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) + +{ + return EFI_SUCCESS; +} +"""), +TemplateString(""" +GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = ${PiSpecVersion}; +${BEGIN} +EFI_STATUS +EFIAPI +ProcessModuleEntryPointList ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) + +{ + return ${Function} (FileHandle, PeiServices); +} +${END} +"""), +TemplateString(""" +GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = ${PiSpecVersion}; + +EFI_STATUS +EFIAPI +ProcessModuleEntryPointList ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) + +{ + EFI_STATUS Status; + EFI_STATUS CombinedStatus; + + CombinedStatus = EFI_LOAD_ERROR; +${BEGIN} + Status = ${Function} (FileHandle, PeiServices); + if (!EFI_ERROR (Status) || EFI_ERROR (CombinedStatus)) { + CombinedStatus = Status; + } +${END} + return CombinedStatus; +} +""") +] + +## DXE SMM Entry Point Templates +gDxeSmmEntryPointPrototype = TemplateString(""" +${BEGIN} +EFI_STATUS +EFIAPI +${Function} ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); +${END} +""") + +gDxeSmmEntryPointString = [ +TemplateString(""" +const UINT32 _gUefiDriverRevision = ${EfiSpecVersion}; +const UINT32 _gDxeRevision = ${PiSpecVersion}; + +EFI_STATUS +EFIAPI +ProcessModuleEntryPointList ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) + +{ + return EFI_SUCCESS; +} +"""), +TemplateString(""" +const UINT32 _gUefiDriverRevision = ${EfiSpecVersion}; +const UINT32 _gDxeRevision = ${PiSpecVersion}; + +static BASE_LIBRARY_JUMP_BUFFER mJumpContext; +static EFI_STATUS mDriverEntryPointStatus = EFI_LOAD_ERROR; + +VOID +EFIAPI +ExitDriver ( + IN EFI_STATUS Status + ) +{ + if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) { + mDriverEntryPointStatus = Status; + } + LongJump (&mJumpContext, (UINTN)-1); + ASSERT (FALSE); +} + +EFI_STATUS +EFIAPI +ProcessModuleEntryPointList ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) + +{ +${BEGIN} + if (SetJump (&mJumpContext) == 0) { + ExitDriver (${Function} (ImageHandle, SystemTable)); + ASSERT (FALSE); + } +${END} + + return mDriverEntryPointStatus; +} +""") +] + +## UEFI Driver Entry Point Templates +gUefiDriverEntryPointPrototype = TemplateString(""" +${BEGIN} +EFI_STATUS +EFIAPI +${Function} ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); +${END} +""") + +gUefiDriverEntryPointString = [ +TemplateString(""" +const UINT32 _gUefiDriverRevision = ${EfiSpecVersion}; +const UINT32 _gDxeRevision = ${PiSpecVersion}; + +EFI_STATUS +EFIAPI +ProcessModuleEntryPointList ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + return EFI_SUCCESS; +} +"""), +TemplateString(""" +const UINT32 _gUefiDriverRevision = ${EfiSpecVersion}; +const UINT32 _gDxeRevision = ${PiSpecVersion}; + +${BEGIN} +EFI_STATUS +EFIAPI +ProcessModuleEntryPointList ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) + +{ + return ${Function} (ImageHandle, SystemTable); +} +${END} +VOID +EFIAPI +ExitDriver ( + IN EFI_STATUS Status + ) +{ + if (EFI_ERROR (Status)) { + ProcessLibraryDestructorList (gImageHandle, gST); + } + gBS->Exit (gImageHandle, Status, 0, NULL); +} +"""), +TemplateString(""" +const UINT32 _gUefiDriverRevision = ${EfiSpecVersion}; +const UINT32 _gDxeRevision = ${PiSpecVersion}; + +EFI_STATUS +EFIAPI +ProcessModuleEntryPointList ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) + +{ + ${BEGIN} + if (SetJump (&mJumpContext) == 0) { + ExitDriver (${Function} (ImageHandle, SystemTable)); + ASSERT (FALSE); + } + ${END} + return mDriverEntryPointStatus; +} + +static BASE_LIBRARY_JUMP_BUFFER mJumpContext; +static EFI_STATUS mDriverEntryPointStatus = EFI_LOAD_ERROR; + +VOID +EFIAPI +ExitDriver ( + IN EFI_STATUS Status + ) +{ + if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) { + mDriverEntryPointStatus = Status; + } + LongJump (&mJumpContext, (UINTN)-1); + ASSERT (FALSE); +} +""") +] + + +## UEFI Application Entry Point Templates +gUefiApplicationEntryPointPrototype = TemplateString(""" +${BEGIN} +EFI_STATUS +EFIAPI +${Function} ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); +${END} +""") + +gUefiApplicationEntryPointString = [ +TemplateString(""" +const UINT32 _gUefiDriverRevision = ${EfiSpecVersion}; + +EFI_STATUS +EFIAPI +ProcessModuleEntryPointList ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + return EFI_SUCCESS; +} +"""), +TemplateString(""" +const UINT32 _gUefiDriverRevision = ${EfiSpecVersion}; + +${BEGIN} +EFI_STATUS +EFIAPI +ProcessModuleEntryPointList ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) + +{ + return ${Function} (ImageHandle, SystemTable); +} +${END} +VOID +EFIAPI +ExitDriver ( + IN EFI_STATUS Status + ) +{ + if (EFI_ERROR (Status)) { + ProcessLibraryDestructorList (gImageHandle, gST); + } + gBS->Exit (gImageHandle, Status, 0, NULL); +} +"""), +TemplateString(""" +const UINT32 _gUefiDriverRevision = ${EfiSpecVersion}; + +EFI_STATUS +EFIAPI +ProcessModuleEntryPointList ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) + +{ + ${BEGIN} + if (SetJump (&mJumpContext) == 0) { + ExitDriver (${Function} (ImageHandle, SystemTable)); + ASSERT (FALSE); + } + ${END} + return mDriverEntryPointStatus; +} + +static BASE_LIBRARY_JUMP_BUFFER mJumpContext; +static EFI_STATUS mDriverEntryPointStatus = EFI_LOAD_ERROR; + +VOID +EFIAPI +ExitDriver ( + IN EFI_STATUS Status + ) +{ + if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) { + mDriverEntryPointStatus = Status; + } + LongJump (&mJumpContext, (UINTN)-1); + ASSERT (FALSE); +} +""") +] + +## UEFI Unload Image Templates +gUefiUnloadImagePrototype = TemplateString(""" +${BEGIN} +EFI_STATUS +EFIAPI +${Function} ( + IN EFI_HANDLE ImageHandle + ); +${END} +""") + +gUefiUnloadImageString = [ +TemplateString(""" +GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count}; + +EFI_STATUS +EFIAPI +ProcessModuleUnloadList ( + IN EFI_HANDLE ImageHandle + ) +{ + return EFI_SUCCESS; +} +"""), +TemplateString(""" +GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count}; + +${BEGIN} +EFI_STATUS +EFIAPI +ProcessModuleUnloadList ( + IN EFI_HANDLE ImageHandle + ) +{ + return ${Function} (ImageHandle); +} +${END} +"""), +TemplateString(""" +GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count}; + +EFI_STATUS +EFIAPI +ProcessModuleUnloadList ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + + Status = EFI_SUCCESS; +${BEGIN} + if (EFI_ERROR (Status)) { + ${Function} (ImageHandle); + } else { + Status = ${Function} (ImageHandle); + } +${END} + return Status; +} +""") +] + +gLibraryStructorPrototype = { +'BASE' : TemplateString("""${BEGIN} +RETURN_STATUS +EFIAPI +${Function} ( + VOID + );${END} +"""), + +'PEI' : TemplateString("""${BEGIN} +EFI_STATUS +EFIAPI +${Function} ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + );${END} +"""), + +'DXE' : TemplateString("""${BEGIN} +EFI_STATUS +EFIAPI +${Function} ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + );${END} +"""), +} + +gLibraryStructorCall = { +'BASE' : TemplateString("""${BEGIN} + Status = ${Function} (); + ASSERT_EFI_ERROR (Status);${END} +"""), + +'PEI' : TemplateString("""${BEGIN} + Status = ${Function} (FileHandle, PeiServices); + ASSERT_EFI_ERROR (Status);${END} +"""), + +'DXE' : TemplateString("""${BEGIN} + Status = ${Function} (ImageHandle, SystemTable); + ASSERT_EFI_ERROR (Status);${END} +"""), +} + +## Library Constructor and Destructor Templates +gLibraryString = { +'BASE' : TemplateString(""" +${BEGIN}${FunctionPrototype}${END} + +VOID +EFIAPI +ProcessLibrary${Type}List ( + VOID + ) +{ +${BEGIN} EFI_STATUS Status; +${FunctionCall}${END} +} +"""), + +'PEI' : TemplateString(""" +${BEGIN}${FunctionPrototype}${END} + +VOID +EFIAPI +ProcessLibrary${Type}List ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ +${BEGIN} EFI_STATUS Status; +${FunctionCall}${END} +} +"""), + +'DXE' : TemplateString(""" +${BEGIN}${FunctionPrototype}${END} + +VOID +EFIAPI +ProcessLibrary${Type}List ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ +${BEGIN} EFI_STATUS Status; +${FunctionCall}${END} +} +"""), +} + +gSpecificationString = TemplateString(""" +${BEGIN} +#undef ${SpecificationName} +#define ${SpecificationName} ${SpecificationValue} +${END} +""") + +gBasicHeaderFile = "Base.h" + +gModuleTypeHeaderFile = { + "BASE" : [gBasicHeaderFile], + "SEC" : ["PiPei.h", "Library/DebugLib.h"], + "PEI_CORE" : ["PiPei.h", "Library/DebugLib.h", "Library/PeiCoreEntryPoint.h"], + "PEIM" : ["PiPei.h", "Library/DebugLib.h", "Library/PeimEntryPoint.h"], + "DXE_CORE" : ["PiDxe.h", "Library/DebugLib.h", "Library/DxeCoreEntryPoint.h"], + "DXE_DRIVER" : ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"], + "DXE_SMM_DRIVER" : ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"], + "DXE_RUNTIME_DRIVER": ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"], + "DXE_SAL_DRIVER" : ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"], + "UEFI_DRIVER" : ["Uefi.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"], + "UEFI_APPLICATION" : ["Uefi.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiApplicationEntryPoint.h"], + "SMM_DRIVER" : ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/SmmDriverEntryPoint.h"], + "SMM_CORE" : ["PiDxe.h", "Library/DebugLib.h"], + "USER_DEFINED" : [gBasicHeaderFile] +} + +## Create code for module PCDs +# +# @param Info The ModuleAutoGen object +# @param AutoGenC The TemplateString object for C code +# @param AutoGenH The TemplateString object for header file +# @param Pcd The PCD object +# +def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd): + TokenSpaceGuidValue = Pcd.TokenSpaceGuidValue #Info.GuidList[Pcd.TokenSpaceGuidCName] + PcdTokenNumber = Info.PlatformInfo.PcdTokenNumber + # + # Write PCDs + # + PcdTokenName = '_PCD_TOKEN_' + Pcd.TokenCName + if Pcd.Type in gDynamicExPcd: + TokenNumber = int(Pcd.TokenValue, 0) + else: + if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) not in PcdTokenNumber: + EdkLogger.error("build", AUTOGEN_ERROR, + "No generated token number for %s.%s\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName), + ExtraData="[%s]" % str(Info)) + TokenNumber = PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] + AutoGenH.Append('\n#define %s %d\n' % (PcdTokenName, TokenNumber)) + + EdkLogger.debug(EdkLogger.DEBUG_3, "Creating code for " + Pcd.TokenCName + "." + Pcd.TokenSpaceGuidCName) + if Pcd.Type not in gItemTypeStringDatabase: + EdkLogger.error("build", AUTOGEN_ERROR, + "Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, Pcd.TokenCName), + ExtraData="[%s]" % str(Info)) + if Pcd.DatumType not in gDatumSizeStringDatabase: + EdkLogger.error("build", AUTOGEN_ERROR, + "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName), + ExtraData="[%s]" % str(Info)) + + DatumSize = gDatumSizeStringDatabase[Pcd.DatumType] + DatumSizeLib = gDatumSizeStringDatabaseLib[Pcd.DatumType] + GetModeName = '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName + SetModeName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName + + if Pcd.Type in gDynamicExPcd: + AutoGenH.Append('#define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName)) + if Pcd.DatumType == 'VOID*': + AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName)) + else: + AutoGenH.Append('#define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName)) + elif Pcd.Type in gDynamicPcd: + AutoGenH.Append('#define %s LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName)) + if Pcd.DatumType == 'VOID*': + AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName)) + else: + AutoGenH.Append('#define %s(Value) LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName)) + else: + PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[Pcd.Type] + '_' + Pcd.TokenCName + Const = 'const' + if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE: + Const = '' + Type = '' + Array = '' + Value = Pcd.DefaultValue + Unicode = False + if Pcd.DatumType == 'UINT64': + if not Value.endswith('ULL'): + Value += 'ULL' + if Pcd.DatumType == 'VOID*': + if Pcd.MaxDatumSize == None or Pcd.MaxDatumSize == '': + EdkLogger.error("build", AUTOGEN_ERROR, + "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName), + ExtraData="[%s]" % str(Info)) + + ArraySize = int(Pcd.MaxDatumSize, 0) + if Value[0] == '{': + Type = '(VOID *)' + else: + if Value[0] == 'L': + Unicode = True + Value = Value.lstrip('L') #.strip('"') + Value = eval(Value) # translate escape character + NewValue = '{' + for Index in range(0,len(Value)): + if Unicode: + NewValue = NewValue + str(ord(Value[Index]) % 0x10000) + ', ' + else: + NewValue = NewValue + str(ord(Value[Index]) % 0x100) + ', ' + if Unicode: + ArraySize = ArraySize / 2; + + if ArraySize < (len(Value) + 1): + ArraySize = len(Value) + 1 + Value = NewValue + '0 }' + Array = '[%d]' % ArraySize + # + # skip casting for fixed at build since it breaks ARM assembly. + # Long term we need PCD macros that work in assembly + # + elif Pcd.Type != TAB_PCDS_FIXED_AT_BUILD: + Value = "((%s)%s)" % (Pcd.DatumType, Value) + + if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE: + PcdValueName = '_PCD_PATCHABLE_VALUE_' + Pcd.TokenCName + else: + PcdValueName = '_PCD_VALUE_' + Pcd.TokenCName + + if Pcd.DatumType == 'VOID*': + # + # For unicode, UINT16 array will be generated, so the alignment of unicode is guaranteed. + # + if Unicode: + AutoGenH.Append('#define _PCD_PATCHABLE_%s_SIZE %s\n' % (Pcd.TokenCName, Pcd.MaxDatumSize)) + AutoGenH.Append('#define %s %s%s\n' %(PcdValueName, Type, PcdVariableName)) + AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s UINT16 %s%s = %s;\n' % (Const, PcdVariableName, Array, Value)) + AutoGenH.Append('extern %s UINT16 %s%s;\n' %(Const, PcdVariableName, Array)) + AutoGenH.Append('#define %s %s%s\n' %(GetModeName, Type, PcdVariableName)) + else: + AutoGenH.Append('#define _PCD_PATCHABLE_%s_SIZE %s\n' % (Pcd.TokenCName, Pcd.MaxDatumSize)) + AutoGenH.Append('#define %s %s%s\n' %(PcdValueName, Type, PcdVariableName)) + AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s UINT8 %s%s = %s;\n' % (Const, PcdVariableName, Array, Value)) + AutoGenH.Append('extern %s UINT8 %s%s;\n' %(Const, PcdVariableName, Array)) + AutoGenH.Append('#define %s %s%s\n' %(GetModeName, Type, PcdVariableName)) + elif Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE: + AutoGenH.Append('#define %s %s\n' %(PcdValueName, Value)) + AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED volatile %s %s %s = %s;\n' %(Const, Pcd.DatumType, PcdVariableName, PcdValueName)) + AutoGenH.Append('extern volatile %s %s %s%s;\n' % (Const, Pcd.DatumType, PcdVariableName, Array)) + AutoGenH.Append('#define %s %s%s\n' % (GetModeName, Type, PcdVariableName)) + else: + AutoGenH.Append('#define %s %s\n' %(PcdValueName, Value)) + AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s %s = %s;\n' %(Const, Pcd.DatumType, PcdVariableName, PcdValueName)) + AutoGenH.Append('extern %s %s %s%s;\n' % (Const, Pcd.DatumType, PcdVariableName, Array)) + AutoGenH.Append('#define %s %s%s\n' % (GetModeName, Type, PcdVariableName)) + + if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE: + if Pcd.DatumType == 'VOID*': + AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPatchPcdSetPtr(_gPcd_BinaryPatch_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeName, Pcd.TokenCName, Pcd.TokenCName)) + else: + AutoGenH.Append('#define %s(Value) (%s = (Value))\n' % (SetModeName, PcdVariableName)) + else: + AutoGenH.Append('//#define %s ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD\n' % SetModeName) + +## Create code for library module PCDs +# +# @param Info The ModuleAutoGen object +# @param AutoGenC The TemplateString object for C code +# @param AutoGenH The TemplateString object for header file +# @param Pcd The PCD object +# +def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd): + PcdTokenNumber = Info.PlatformInfo.PcdTokenNumber + TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName + TokenCName = Pcd.TokenCName + TokenSpaceGuidValue = Pcd.TokenSpaceGuidValue #Info.GuidList[TokenSpaceGuidCName] + if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) not in PcdTokenNumber: + EdkLogger.error("build", AUTOGEN_ERROR, + "No generated token number for %s.%s\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName), + ExtraData="[%s]" % str(Info)) + TokenNumber = PcdTokenNumber[TokenCName, TokenSpaceGuidCName] + + if Pcd.Type not in gItemTypeStringDatabase: + EdkLogger.error("build", AUTOGEN_ERROR, + "Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, Pcd.TokenCName), + ExtraData="[%s]" % str(Info)) + if Pcd.DatumType not in gDatumSizeStringDatabase: + EdkLogger.error("build", AUTOGEN_ERROR, + "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName), + ExtraData="[%s]" % str(Info)) + + DatumType = Pcd.DatumType + DatumSize = gDatumSizeStringDatabaseH[DatumType] + DatumSizeLib= gDatumSizeStringDatabaseLib[DatumType] + GetModeName = '_PCD_GET_MODE_' + DatumSize + '_' + TokenCName + SetModeName = '_PCD_SET_MODE_' + DatumSize + '_' + TokenCName + + Type = '' + Array = '' + if Pcd.DatumType == 'VOID*': + Type = '(VOID *)' + Array = '[]' + + AutoGenH.Append('#define _PCD_TOKEN_%s %d\n' % (TokenCName, TokenNumber)) + + PcdItemType = Pcd.Type + #if PcdItemType in gDynamicPcd: + # PcdItemType = TAB_PCDS_FIXED_AT_BUILD + # if (TokenCName, TokenSpaceGuidCName) in Info.PlatformInfo.Platform.Pcds: + # PcdItemType = Info.PlatformInfo.Platform.Pcds[TokenCName, TokenSpaceGuidCName].Type + if PcdItemType in gDynamicExPcd: + PcdTokenName = '_PCD_TOKEN_' + TokenCName + AutoGenH.Append('#define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, TokenSpaceGuidCName, PcdTokenName)) + if DatumType == 'VOID*': + AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName,DatumSizeLib, TokenSpaceGuidCName, PcdTokenName)) + else: + AutoGenH.Append('#define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, TokenSpaceGuidCName, PcdTokenName)) + if PcdItemType in gDynamicPcd: + PcdTokenName = '_PCD_TOKEN_' + TokenCName + AutoGenH.Append('#define %s LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName)) + if DatumType == 'VOID*': + AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName)) + else: + AutoGenH.Append('#define %s(Value) LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName)) + if PcdItemType == TAB_PCDS_PATCHABLE_IN_MODULE: + PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[TAB_PCDS_PATCHABLE_IN_MODULE] + '_' + TokenCName + AutoGenH.Append('extern %s _gPcd_BinaryPatch_%s%s;\n' %(DatumType, TokenCName, Array) ) + AutoGenH.Append('#define %s %s_gPcd_BinaryPatch_%s\n' %(GetModeName, Type, TokenCName)) + AutoGenH.Append('#define %s(Value) (%s = (Value))\n' % (SetModeName, PcdVariableName)) + if PcdItemType == TAB_PCDS_FIXED_AT_BUILD or PcdItemType == TAB_PCDS_FEATURE_FLAG: + AutoGenH.Append('extern const %s _gPcd_FixedAtBuild_%s%s;\n' %(DatumType, TokenCName, Array)) + #AutoGenH.Append('#define _PCD_VALUE_%s _gPcd_FixedAtBuild_%s\n' %(TokenCName, TokenCName)) + AutoGenH.Append('#define %s %s_gPcd_FixedAtBuild_%s\n' %(GetModeName, Type, TokenCName)) + AutoGenH.Append('//#define %s ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD\n' % SetModeName) + +## Create code for PCD database in DXE or PEI phase +# +# @param Platform The platform object +# @retval tuple Two TemplateString objects for C code and header file, +# respectively +# +def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase): + AutoGenC = TemplateString() + AutoGenH = TemplateString() + + Dict = { + 'PHASE' : Phase, + 'GUID_TABLE_SIZE' : '1', + 'STRING_TABLE_SIZE' : '1', + 'SKUID_TABLE_SIZE' : '1', + 'LOCAL_TOKEN_NUMBER_TABLE_SIZE' : '1', + 'LOCAL_TOKEN_NUMBER' : '0', + 'EXMAPPING_TABLE_SIZE' : '1', + 'EX_TOKEN_NUMBER' : '0', + 'SIZE_TABLE_SIZE' : '2', + 'GUID_TABLE_EMPTY' : 'TRUE', + 'STRING_TABLE_EMPTY' : 'TRUE', + 'SKUID_TABLE_EMPTY' : 'TRUE', + 'DATABASE_EMPTY' : 'TRUE', + 'EXMAP_TABLE_EMPTY' : 'TRUE', + 'PCD_DATABASE_UNINIT_EMPTY' : ' UINT8 dummy; /* PCD_DATABASE_UNINIT is emptry */', + 'SYSTEM_SKU_ID' : ' SKU_ID SystemSkuId;', + 'SYSTEM_SKU_ID_VALUE' : '0' + } + + for DatumType in ['UINT64','UINT32','UINT16','UINT8','BOOLEAN']: + Dict['VARDEF_CNAME_' + DatumType] = [] + Dict['VARDEF_GUID_' + DatumType] = [] + Dict['VARDEF_SKUID_' + DatumType] = [] + Dict['VARDEF_VALUE_' + DatumType] = [] + for Init in ['INIT','UNINIT']: + Dict[Init+'_CNAME_DECL_' + DatumType] = [] + Dict[Init+'_GUID_DECL_' + DatumType] = [] + Dict[Init+'_NUMSKUS_DECL_' + DatumType] = [] + Dict[Init+'_VALUE_' + DatumType] = [] + + for Type in ['STRING_HEAD','VPD_HEAD','VARIABLE_HEAD']: + Dict[Type + '_CNAME_DECL'] = [] + Dict[Type + '_GUID_DECL'] = [] + Dict[Type + '_NUMSKUS_DECL'] = [] + Dict[Type + '_VALUE'] = [] + + Dict['STRING_TABLE_INDEX'] = [] + Dict['STRING_TABLE_LENGTH'] = [] + Dict['STRING_TABLE_CNAME'] = [] + Dict['STRING_TABLE_GUID'] = [] + Dict['STRING_TABLE_VALUE'] = [] + + Dict['SIZE_TABLE_CNAME'] = [] + Dict['SIZE_TABLE_GUID'] = [] + Dict['SIZE_TABLE_CURRENT_LENGTH'] = [] + Dict['SIZE_TABLE_MAXIMUM_LENGTH'] = [] + + Dict['EXMAPPING_TABLE_EXTOKEN'] = [] + Dict['EXMAPPING_TABLE_LOCAL_TOKEN'] = [] + Dict['EXMAPPING_TABLE_GUID_INDEX'] = [] + + Dict['GUID_STRUCTURE'] = [] + + Dict['SKUID_VALUE'] = [] + + if Phase == 'DXE': + Dict['SYSTEM_SKU_ID'] = '' + Dict['SYSTEM_SKU_ID_VALUE'] = '' + + StringTableIndex = 0 + StringTableSize = 0 + NumberOfLocalTokens = 0 + NumberOfPeiLocalTokens = 0 + NumberOfDxeLocalTokens = 0 + NumberOfExTokens = 0 + NumberOfSizeItems = 0 + GuidList = [] + + for Pcd in Platform.DynamicPcdList: + CName = Pcd.TokenCName + TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName + + EdkLogger.debug(EdkLogger.DEBUG_3, "PCD: %s %s (%s : %s)" % (CName, TokenSpaceGuidCName, Pcd.Phase, Phase)) + if Pcd.DatumType not in gDatumSizeStringDatabase: + EdkLogger.error("build", AUTOGEN_ERROR, + "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName), + ExtraData="[%s]" % str(Platform)) + + if Pcd.Phase == 'PEI': + NumberOfPeiLocalTokens += 1 + if Pcd.Phase == 'DXE': + NumberOfDxeLocalTokens += 1 + if Pcd.Phase != Phase: + continue + + # + # TODO: need GetGuidValue() definition + # + TokenSpaceGuidStructure = Pcd.TokenSpaceGuidValue + TokenSpaceGuid = GuidStructureStringToGuidValueName(TokenSpaceGuidStructure) + if Pcd.Type in gDynamicExPcd: + if TokenSpaceGuid not in GuidList: + GuidList += [TokenSpaceGuid] + Dict['GUID_STRUCTURE'].append(TokenSpaceGuidStructure) + NumberOfExTokens += 1 + + ValueList = [] + StringHeadOffsetList = [] + VpdHeadOffsetList = [] + VariableHeadValueList = [] + Pcd.InitString = 'UNINIT' + + if Pcd.DatumType == 'VOID*': + Pcd.TokenTypeList = ['PCD_DATUM_TYPE_POINTER'] + elif Pcd.DatumType == 'BOOLEAN': + Pcd.TokenTypeList = ['PCD_DATUM_TYPE_UINT8'] + else: + Pcd.TokenTypeList = ['PCD_DATUM_TYPE_' + Pcd.DatumType] + + if len(Pcd.SkuInfoList) > 1: + Pcd.TokenTypeList += ['PCD_TYPE_SKU_ENABLED'] + + for SkuName in Pcd.SkuInfoList: + Sku = Pcd.SkuInfoList[SkuName] + SkuId = Sku.SkuId + if SkuId == None or SkuId == '': + continue + + if SkuId not in Dict['SKUID_VALUE']: + Dict['SKUID_VALUE'].append(SkuId) + + SkuIdIndex = Dict['SKUID_VALUE'].index(SkuId) + if len(Sku.VariableName) > 0: + Pcd.TokenTypeList += ['PCD_TYPE_HII'] + Pcd.InitString = 'INIT' + VariableNameStructure = StringToArray(Sku.VariableName) + if VariableNameStructure not in Dict['STRING_TABLE_VALUE']: + Dict['STRING_TABLE_CNAME'].append(CName) + Dict['STRING_TABLE_GUID'].append(TokenSpaceGuid) + if StringTableIndex == 0: + Dict['STRING_TABLE_INDEX'].append('') + else: + Dict['STRING_TABLE_INDEX'].append('_%d' % StringTableIndex) + + Dict['STRING_TABLE_LENGTH'].append((len(Sku.VariableName) - 3 + 1) * 2) + Dict['STRING_TABLE_VALUE'].append(VariableNameStructure) + StringTableIndex += 1 + StringTableSize += (len(Sku.VariableName) - 3 + 1) * 2 + + VariableHeadStringIndex = 0 + for Index in range(Dict['STRING_TABLE_VALUE'].index(VariableNameStructure)): + VariableHeadStringIndex += Dict['STRING_TABLE_LENGTH'][Index] + + VariableGuidStructure = Sku.VariableGuidValue + VariableGuid = GuidStructureStringToGuidValueName(VariableGuidStructure) + if VariableGuid not in GuidList: + GuidList += [VariableGuid] + Dict['GUID_STRUCTURE'].append(VariableGuidStructure) + VariableHeadGuidIndex = GuidList.index(VariableGuid) + + VariableHeadValueList.append('%d, %d, %s, offsetof(%s_PCD_DATABASE, Init.%s_%s_VariableDefault_%s)' % + (VariableHeadGuidIndex, VariableHeadStringIndex, Sku.VariableOffset, + Phase, CName, TokenSpaceGuid, SkuIdIndex)) + Dict['VARDEF_CNAME_'+Pcd.DatumType].append(CName) + Dict['VARDEF_GUID_'+Pcd.DatumType].append(TokenSpaceGuid) + Dict['VARDEF_SKUID_'+Pcd.DatumType].append(SkuIdIndex) + Dict['VARDEF_VALUE_'+Pcd.DatumType].append(Sku.HiiDefaultValue) + elif Sku.VpdOffset != '': + Pcd.TokenTypeList += ['PCD_TYPE_VPD'] + Pcd.InitString = 'INIT' + VpdHeadOffsetList.append(Sku.VpdOffset) + else: + if Pcd.DatumType == 'VOID*': + Pcd.TokenTypeList += ['PCD_TYPE_STRING'] + Pcd.InitString = 'INIT' + if Sku.DefaultValue != '': + NumberOfSizeItems += 1 + Dict['STRING_TABLE_CNAME'].append(CName) + Dict['STRING_TABLE_GUID'].append(TokenSpaceGuid) + + if StringTableIndex == 0: + Dict['STRING_TABLE_INDEX'].append('') + else: + Dict['STRING_TABLE_INDEX'].append('_%d' % StringTableIndex) + if Sku.DefaultValue[0] == 'L': + Size = (len(Sku.DefaultValue) - 3 + 1) * 2 + Dict['STRING_TABLE_VALUE'].append(StringToArray(Sku.DefaultValue)) + elif Sku.DefaultValue[0] == '"': + Size = len(Sku.DefaultValue) - 2 + 1 + Dict['STRING_TABLE_VALUE'].append(StringToArray(Sku.DefaultValue)) + elif Sku.DefaultValue[0] == '{': + Size = len(Sku.DefaultValue.replace(',',' ').split()) + Dict['STRING_TABLE_VALUE'].append(Sku.DefaultValue) + + StringHeadOffsetList.append(str(StringTableSize)) + Dict['SIZE_TABLE_CNAME'].append(CName) + Dict['SIZE_TABLE_GUID'].append(TokenSpaceGuid) + Dict['SIZE_TABLE_CURRENT_LENGTH'].append(Size) + Dict['SIZE_TABLE_MAXIMUM_LENGTH'].append(Pcd.MaxDatumSize) + if Pcd.MaxDatumSize != '': + MaxDatumSize = int(Pcd.MaxDatumSize, 0) + if MaxDatumSize > Size: + Size = MaxDatumSize + Dict['STRING_TABLE_LENGTH'].append(Size) + StringTableIndex += 1 + StringTableSize += (Size) + else: + Pcd.TokenTypeList += ['PCD_TYPE_DATA'] + if Sku.DefaultValue == 'TRUE': + Pcd.InitString = 'INIT' + else: + try: + if int(Sku.DefaultValue, 0) != 0: + Pcd.InitString = 'INIT' + except: + pass + + # + # For UNIT64 type PCD's value, ULL should be append to avoid + # warning under linux building environment. + # + if Pcd.DatumType == "UINT64": + ValueList.append(Sku.DefaultValue + "ULL") + else: + ValueList.append(Sku.DefaultValue) + + Pcd.TokenTypeList = list(set(Pcd.TokenTypeList)) + + if 'PCD_TYPE_HII' in Pcd.TokenTypeList: + Dict['VARIABLE_HEAD_CNAME_DECL'].append(CName) + Dict['VARIABLE_HEAD_GUID_DECL'].append(TokenSpaceGuid) + Dict['VARIABLE_HEAD_NUMSKUS_DECL'].append(len(Pcd.SkuInfoList)) + Dict['VARIABLE_HEAD_VALUE'].append('{ %s }\n' % ' },\n { '.join(VariableHeadValueList)) + if 'PCD_TYPE_VPD' in Pcd.TokenTypeList: + Dict['VPD_HEAD_CNAME_DECL'].append(CName) + Dict['VPD_HEAD_GUID_DECL'].append(TokenSpaceGuid) + Dict['VPD_HEAD_NUMSKUS_DECL'].append(len(Pcd.SkuInfoList)) + Dict['VPD_HEAD_VALUE'].append('{ %s }' % ' }, { '.join(VpdHeadOffsetList)) + if 'PCD_TYPE_STRING' in Pcd.TokenTypeList: + Dict['STRING_HEAD_CNAME_DECL'].append(CName) + Dict['STRING_HEAD_GUID_DECL'].append(TokenSpaceGuid) + Dict['STRING_HEAD_NUMSKUS_DECL'].append(len(Pcd.SkuInfoList)) + Dict['STRING_HEAD_VALUE'].append(', '.join(StringHeadOffsetList)) + if 'PCD_TYPE_DATA' in Pcd.TokenTypeList: + Dict[Pcd.InitString+'_CNAME_DECL_'+Pcd.DatumType].append(CName) + Dict[Pcd.InitString+'_GUID_DECL_'+Pcd.DatumType].append(TokenSpaceGuid) + Dict[Pcd.InitString+'_NUMSKUS_DECL_'+Pcd.DatumType].append(len(Pcd.SkuInfoList)) + if Pcd.InitString == 'UNINIT': + Dict['PCD_DATABASE_UNINIT_EMPTY'] = '' + else: + Dict[Pcd.InitString+'_VALUE_'+Pcd.DatumType].append(', '.join(ValueList)) + + if Phase == 'PEI': + NumberOfLocalTokens = NumberOfPeiLocalTokens + if Phase == 'DXE': + NumberOfLocalTokens = NumberOfDxeLocalTokens + + Dict['TOKEN_INIT'] = ['' for x in range(NumberOfLocalTokens)] + Dict['TOKEN_CNAME'] = ['' for x in range(NumberOfLocalTokens)] + Dict['TOKEN_GUID'] = ['' for x in range(NumberOfLocalTokens)] + Dict['TOKEN_TYPE'] = ['' for x in range(NumberOfLocalTokens)] + + for Pcd in Platform.DynamicPcdList: + CName = Pcd.TokenCName + TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName + if Pcd.Phase != Phase: + continue + + TokenSpaceGuid = GuidStructureStringToGuidValueName(Pcd.TokenSpaceGuidValue) #(Platform.PackageList, TokenSpaceGuidCName)) + GeneratedTokenNumber = Platform.PcdTokenNumber[CName, TokenSpaceGuidCName] - 1 + if Phase == 'DXE': + GeneratedTokenNumber -= NumberOfPeiLocalTokens + + EdkLogger.debug(EdkLogger.DEBUG_1, "PCD = %s.%s" % (CName, TokenSpaceGuidCName)) + EdkLogger.debug(EdkLogger.DEBUG_1, "phase = %s" % Phase) + EdkLogger.debug(EdkLogger.DEBUG_1, "GeneratedTokenNumber = %s" % str(GeneratedTokenNumber)) + + Dict['TOKEN_INIT'][GeneratedTokenNumber] = 'Init' + if Pcd.InitString == 'UNINIT': + Dict['TOKEN_INIT'][GeneratedTokenNumber] = 'Uninit' + Dict['TOKEN_CNAME'][GeneratedTokenNumber] = CName + Dict['TOKEN_GUID'][GeneratedTokenNumber] = TokenSpaceGuid + Dict['TOKEN_TYPE'][GeneratedTokenNumber] = ' | '.join(Pcd.TokenTypeList) + if Pcd.Type in gDynamicExPcd: + Dict['EXMAPPING_TABLE_EXTOKEN'].append(Pcd.TokenValue) + if Phase == 'DXE': + GeneratedTokenNumber += NumberOfPeiLocalTokens + # + # Per, PCD architecture specification, PCD Token Number is 1 based and 0 is defined as invalid token number. + # For each EX type PCD, a PCD Token Number is assigned. When the + # PCD Driver/PEIM map EX_GUID and EX_TOKEN_NUMBER to the PCD Token Number, + # the non-EX Protocol/PPI interface can be called to get/set the value. This assumption is made by + # Pcd Driver/PEIM in MdeModulePkg. + # Therefore, 1 is added to GeneratedTokenNumber to generate a PCD Token Number before being inserted + # to the EXMAPPING_TABLE. + # + Dict['EXMAPPING_TABLE_LOCAL_TOKEN'].append(GeneratedTokenNumber + 1) + Dict['EXMAPPING_TABLE_GUID_INDEX'].append(GuidList.index(TokenSpaceGuid)) + + if GuidList != []: + Dict['GUID_TABLE_EMPTY'] = 'FALSE' + Dict['GUID_TABLE_SIZE'] = len(GuidList) + else: + Dict['GUID_STRUCTURE'] = [GuidStringToGuidStructureString('00000000-0000-0000-0000-000000000000')] + + if StringTableIndex == 0: + Dict['STRING_TABLE_INDEX'].append('') + Dict['STRING_TABLE_LENGTH'].append(1) + Dict['STRING_TABLE_CNAME'].append('') + Dict['STRING_TABLE_GUID'].append('') + Dict['STRING_TABLE_VALUE'].append('{ 0 }') + else: + Dict['STRING_TABLE_EMPTY'] = 'FALSE' + Dict['STRING_TABLE_SIZE'] = StringTableSize + + if Dict['SIZE_TABLE_CNAME'] == []: + Dict['SIZE_TABLE_CNAME'].append('') + Dict['SIZE_TABLE_GUID'].append('') + Dict['SIZE_TABLE_CURRENT_LENGTH'].append(0) + Dict['SIZE_TABLE_MAXIMUM_LENGTH'].append(0) + + if NumberOfLocalTokens != 0: + Dict['DATABASE_EMPTY'] = 'FALSE' + Dict['LOCAL_TOKEN_NUMBER_TABLE_SIZE'] = NumberOfLocalTokens + Dict['LOCAL_TOKEN_NUMBER'] = NumberOfLocalTokens + + if NumberOfExTokens != 0: + Dict['EXMAP_TABLE_EMPTY'] = 'FALSE' + Dict['EXMAPPING_TABLE_SIZE'] = NumberOfExTokens + Dict['EX_TOKEN_NUMBER'] = NumberOfExTokens + else: + Dict['EXMAPPING_TABLE_EXTOKEN'].append(0) + Dict['EXMAPPING_TABLE_LOCAL_TOKEN'].append(0) + Dict['EXMAPPING_TABLE_GUID_INDEX'].append(0) + + if NumberOfSizeItems != 0: + Dict['SIZE_TABLE_SIZE'] = NumberOfSizeItems * 2 + + AutoGenH.Append(gPcdDatabaseAutoGenH.Replace(Dict)) + if NumberOfLocalTokens == 0: + AutoGenC.Append(gEmptyPcdDatabaseAutoGenC.Replace(Dict)) + else: + AutoGenC.Append(gPcdDatabaseAutoGenC.Replace(Dict)) + + return AutoGenH, AutoGenC + +## Create code for PCD database +# +# @param Info The ModuleAutoGen object +# @param AutoGenC The TemplateString object for C code +# @param AutoGenH The TemplateString object for header file +# +def CreatePcdDatabaseCode (Info, AutoGenC, AutoGenH): + if Info.PcdIsDriver == "": + return + if Info.PcdIsDriver not in gPcdPhaseMap: + EdkLogger.error("build", AUTOGEN_ERROR, "Not supported PcdIsDriver type:%s" % Info.PcdIsDriver, + ExtraData="[%s]" % str(Info)) + + AutoGenH.Append(gPcdDatabaseCommonAutoGenH) + AdditionalAutoGenH, AdditionalAutoGenC = CreatePcdDatabasePhaseSpecificAutoGen (Info.PlatformInfo, 'PEI') + AutoGenH.Append(AdditionalAutoGenH.String) + + Phase = gPcdPhaseMap[Info.PcdIsDriver] + if Phase == 'PEI': + AutoGenC.Append(AdditionalAutoGenC.String) + + if Phase == 'DXE': + AdditionalAutoGenH, AdditionalAutoGenC = CreatePcdDatabasePhaseSpecificAutoGen (Info.PlatformInfo, Phase) + AutoGenH.Append(AdditionalAutoGenH.String) + AutoGenC.Append(AdditionalAutoGenC.String) + AutoGenH.Append(gPcdDatabaseEpilogueAutoGenH) + +## Create code for library constructor +# +# @param Info The ModuleAutoGen object +# @param AutoGenC The TemplateString object for C code +# @param AutoGenH The TemplateString object for header file +# +def CreateLibraryConstructorCode(Info, AutoGenC, AutoGenH): + # + # Library Constructors + # + ConstructorPrototypeString = TemplateString() + ConstructorCallingString = TemplateString() + if Info.IsLibrary: + DependentLibraryList = [Info.Module] + else: + DependentLibraryList = Info.DependentLibraryList + for Lib in DependentLibraryList: + if len(Lib.ConstructorList) <= 0: + continue + Dict = {'Function':Lib.ConstructorList} + if Lib.ModuleType in ['BASE', 'SEC']: + ConstructorPrototypeString.Append(gLibraryStructorPrototype['BASE'].Replace(Dict)) + ConstructorCallingString.Append(gLibraryStructorCall['BASE'].Replace(Dict)) + elif Lib.ModuleType in ['PEI_CORE','PEIM']: + ConstructorPrototypeString.Append(gLibraryStructorPrototype['PEI'].Replace(Dict)) + ConstructorCallingString.Append(gLibraryStructorCall['PEI'].Replace(Dict)) + elif Lib.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER', + 'DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION', 'SMM_DRIVER', 'SMM_CORE']: + ConstructorPrototypeString.Append(gLibraryStructorPrototype['DXE'].Replace(Dict)) + ConstructorCallingString.Append(gLibraryStructorCall['DXE'].Replace(Dict)) + + if str(ConstructorPrototypeString) == '': + ConstructorPrototypeList = [] + else: + ConstructorPrototypeList = [str(ConstructorPrototypeString)] + if str(ConstructorCallingString) == '': + ConstructorCallingList = [] + else: + ConstructorCallingList = [str(ConstructorCallingString)] + + Dict = { + 'Type' : 'Constructor', + 'FunctionPrototype' : ConstructorPrototypeList, + 'FunctionCall' : ConstructorCallingList + } + if Info.IsLibrary: + AutoGenH.Append("${BEGIN}${FunctionPrototype}${END}", Dict) + else: + if Info.ModuleType in ['BASE', 'SEC']: + AutoGenC.Append(gLibraryString['BASE'].Replace(Dict)) + elif Info.ModuleType in ['PEI_CORE','PEIM']: + AutoGenC.Append(gLibraryString['PEI'].Replace(Dict)) + elif Info.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER', + 'DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION', 'SMM_DRIVER', 'SMM_CORE']: + AutoGenC.Append(gLibraryString['DXE'].Replace(Dict)) + +## Create code for library destructor +# +# @param Info The ModuleAutoGen object +# @param AutoGenC The TemplateString object for C code +# @param AutoGenH The TemplateString object for header file +# +def CreateLibraryDestructorCode(Info, AutoGenC, AutoGenH): + # + # Library Destructors + # + DestructorPrototypeString = TemplateString() + DestructorCallingString = TemplateString() + if Info.IsLibrary: + DependentLibraryList = [Info.Module] + else: + DependentLibraryList = Info.DependentLibraryList + for Index in range(len(DependentLibraryList)-1, -1, -1): + Lib = DependentLibraryList[Index] + if len(Lib.DestructorList) <= 0: + continue + Dict = {'Function':Lib.DestructorList} + if Lib.ModuleType in ['BASE', 'SEC']: + DestructorPrototypeString.Append(gLibraryStructorPrototype['BASE'].Replace(Dict)) + DestructorCallingString.Append(gLibraryStructorCall['BASE'].Replace(Dict)) + elif Lib.ModuleType in ['PEI_CORE','PEIM']: + DestructorPrototypeString.Append(gLibraryStructorPrototype['PEI'].Replace(Dict)) + DestructorCallingString.Append(gLibraryStructorCall['PEI'].Replace(Dict)) + elif Lib.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER', + 'DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION', 'SMM_DRIVER', 'SMM_CORE']: + DestructorPrototypeString.Append(gLibraryStructorPrototype['DXE'].Replace(Dict)) + DestructorCallingString.Append(gLibraryStructorCall['DXE'].Replace(Dict)) + + if str(DestructorPrototypeString) == '': + DestructorPrototypeList = [] + else: + DestructorPrototypeList = [str(DestructorPrototypeString)] + if str(DestructorCallingString) == '': + DestructorCallingList = [] + else: + DestructorCallingList = [str(DestructorCallingString)] + + Dict = { + 'Type' : 'Destructor', + 'FunctionPrototype' : DestructorPrototypeList, + 'FunctionCall' : DestructorCallingList + } + if Info.IsLibrary: + AutoGenH.Append("${BEGIN}${FunctionPrototype}${END}", Dict) + else: + if Info.ModuleType in ['BASE', 'SEC']: + AutoGenC.Append(gLibraryString['BASE'].Replace(Dict)) + elif Info.ModuleType in ['PEI_CORE','PEIM']: + AutoGenC.Append(gLibraryString['PEI'].Replace(Dict)) + elif Info.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER', + 'DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION', 'SMM_DRIVER', 'SMM_CORE']: + AutoGenC.Append(gLibraryString['DXE'].Replace(Dict)) + + +## Create code for ModuleEntryPoint +# +# @param Info The ModuleAutoGen object +# @param AutoGenC The TemplateString object for C code +# @param AutoGenH The TemplateString object for header file +# +def CreateModuleEntryPointCode(Info, AutoGenC, AutoGenH): + if Info.IsLibrary or Info.ModuleType in ['USER_DEFINED', 'SEC']: + return + # + # Module Entry Points + # + NumEntryPoints = len(Info.Module.ModuleEntryPointList) + if 'PI_SPECIFICATION_VERSION' in Info.Module.Specification: + PiSpecVersion = Info.Module.Specification['PI_SPECIFICATION_VERSION'] + else: + PiSpecVersion = 0 + if 'EFI_SPECIFICATION_VERSION' in Info.Module.Specification: + EfiSpecVersion = Info.Module.Specification['EFI_SPECIFICATION_VERSION'] + else: + EfiSpecVersion = 0 + Dict = { + 'Function' : Info.Module.ModuleEntryPointList, + 'PiSpecVersion' : PiSpecVersion, + 'EfiSpecVersion': EfiSpecVersion + } + + if Info.ModuleType in ['PEI_CORE', 'DXE_CORE', 'SMM_CORE']: + if NumEntryPoints != 1: + EdkLogger.error( + "build", + AUTOGEN_ERROR, + '%s must have exactly one entry point' % Info.ModuleType, + File=str(Info), + ExtraData= ", ".join(Info.Module.ModuleEntryPointList) + ) + if Info.ModuleType == 'PEI_CORE': + AutoGenC.Append(gPeiCoreEntryPointString.Replace(Dict)) + AutoGenH.Append(gPeiCoreEntryPointPrototype.Replace(Dict)) + elif Info.ModuleType == 'DXE_CORE': + AutoGenC.Append(gDxeCoreEntryPointString.Replace(Dict)) + AutoGenH.Append(gDxeCoreEntryPointPrototype.Replace(Dict)) + elif Info.ModuleType == 'SMM_CORE': + AutoGenC.Append(gSmmCoreEntryPointString.Replace(Dict)) + elif Info.ModuleType == 'PEIM': + if NumEntryPoints < 2: + AutoGenC.Append(gPeimEntryPointString[NumEntryPoints].Replace(Dict)) + else: + AutoGenC.Append(gPeimEntryPointString[2].Replace(Dict)) + AutoGenH.Append(gPeimEntryPointPrototype.Replace(Dict)) + elif Info.ModuleType in ['DXE_RUNTIME_DRIVER','DXE_DRIVER','DXE_SMM_DRIVER', + 'DXE_SAL_DRIVER','UEFI_DRIVER', 'SMM_DRIVER']: + if Info.ModuleType in ['DXE_SMM_DRIVER', 'SMM_DRIVER']: + if NumEntryPoints == 0: + AutoGenC.Append(gDxeSmmEntryPointString[0].Replace(Dict)) + else: + AutoGenC.Append(gDxeSmmEntryPointString[1].Replace(Dict)) + AutoGenH.Append(gDxeSmmEntryPointPrototype.Replace(Dict)) + else: + if NumEntryPoints < 2: + AutoGenC.Append(gUefiDriverEntryPointString[NumEntryPoints].Replace(Dict)) + else: + AutoGenC.Append(gUefiDriverEntryPointString[2].Replace(Dict)) + AutoGenH.Append(gUefiDriverEntryPointPrototype.Replace(Dict)) + elif Info.ModuleType == 'UEFI_APPLICATION': + if NumEntryPoints < 2: + AutoGenC.Append(gUefiApplicationEntryPointString[NumEntryPoints].Replace(Dict)) + else: + AutoGenC.Append(gUefiApplicationEntryPointString[2].Replace(Dict)) + AutoGenH.Append(gUefiApplicationEntryPointPrototype.Replace(Dict)) + +## Create code for ModuleUnloadImage +# +# @param Info The ModuleAutoGen object +# @param AutoGenC The TemplateString object for C code +# @param AutoGenH The TemplateString object for header file +# +def CreateModuleUnloadImageCode(Info, AutoGenC, AutoGenH): + if Info.IsLibrary or Info.ModuleType in ['USER_DEFINED', 'SEC']: + return + # + # Unload Image Handlers + # + NumUnloadImage = len(Info.Module.ModuleUnloadImageList) + Dict = {'Count':NumUnloadImage, 'Function':Info.Module.ModuleUnloadImageList} + if NumUnloadImage < 2: + AutoGenC.Append(gUefiUnloadImageString[NumUnloadImage].Replace(Dict)) + else: + AutoGenC.Append(gUefiUnloadImageString[2].Replace(Dict)) + AutoGenH.Append(gUefiUnloadImagePrototype.Replace(Dict)) + +## Create code for GUID +# +# @param Info The ModuleAutoGen object +# @param AutoGenC The TemplateString object for C code +# @param AutoGenH The TemplateString object for header file +# +def CreateGuidDefinitionCode(Info, AutoGenC, AutoGenH): + if Info.IsLibrary: + return + + if Info.ModuleType in ["USER_DEFINED", "BASE"]: + GuidType = "GUID" + else: + GuidType = "EFI_GUID" + + if Info.GuidList: + AutoGenC.Append("\n// Guids\n") + # + # GUIDs + # + for Key in Info.GuidList: + AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.GuidList[Key])) + +## Create code for protocol +# +# @param Info The ModuleAutoGen object +# @param AutoGenC The TemplateString object for C code +# @param AutoGenH The TemplateString object for header file +# +def CreateProtocolDefinitionCode(Info, AutoGenC, AutoGenH): + if Info.IsLibrary: + return + + if Info.ModuleType in ["USER_DEFINED", "BASE"]: + GuidType = "GUID" + else: + GuidType = "EFI_GUID" + + if Info.ProtocolList: + AutoGenC.Append("\n// Protocols\n") + # + # Protocol GUIDs + # + for Key in Info.ProtocolList: + AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.ProtocolList[Key])) + +## Create code for PPI +# +# @param Info The ModuleAutoGen object +# @param AutoGenC The TemplateString object for C code +# @param AutoGenH The TemplateString object for header file +# +def CreatePpiDefinitionCode(Info, AutoGenC, AutoGenH): + if Info.IsLibrary: + return + + if Info.ModuleType in ["USER_DEFINED", "BASE"]: + GuidType = "GUID" + else: + GuidType = "EFI_GUID" + + if Info.PpiList: + AutoGenC.Append("\n// PPIs\n") + # + # PPI GUIDs + # + for Key in Info.PpiList: + AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.PpiList[Key])) + +## Create code for PCD +# +# @param Info The ModuleAutoGen object +# @param AutoGenC The TemplateString object for C code +# @param AutoGenH The TemplateString object for header file +# +def CreatePcdCode(Info, AutoGenC, AutoGenH): + if Info.IsLibrary: + if Info.ModulePcdList: + AutoGenH.Append("\n// PCD definitions\n") + for Pcd in Info.ModulePcdList: + CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd) + else: + if Info.ModulePcdList: + AutoGenH.Append("\n// Definition of PCDs used in this module\n") + AutoGenC.Append("\n// Definition of PCDs used in this module\n") + for Pcd in Info.ModulePcdList: + CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd) + + if Info.LibraryPcdList: + AutoGenH.Append("\n// Definition of PCDs used in libraries is in AutoGen.c\n") + AutoGenC.Append("\n// Definition of PCDs used in libraries\n") + for Pcd in Info.LibraryPcdList: + CreateModulePcdCode(Info, AutoGenC, AutoGenC, Pcd) + CreatePcdDatabaseCode(Info, AutoGenC, AutoGenH) + +## Create code for unicode string definition +# +# @param Info The ModuleAutoGen object +# @param AutoGenC The TemplateString object for C code +# @param AutoGenH The TemplateString object for header file +# +def CreateUnicodeStringCode(Info, AutoGenC, AutoGenH): + WorkingDir = os.getcwd() + os.chdir(Info.WorkspaceDir) + + IncList = [Info.MetaFile.Dir] + # Get all files under [Sources] section in inf file for EDK-II module + SrcList = [F for F in Info.SourceFileList] + if Info.AutoGenVersion < 0x00010005: + # Get all files under the module directory for EDK-I module + Cwd = os.getcwd() + os.chdir(Info.MetaFile.Dir) + for Root, Dirs, Files in os.walk("."): + if 'CVS' in Dirs: + Dirs.remove('CVS') + if '.svn' in Dirs: + Dirs.remove('.svn') + for File in Files: + File = PathClass(os.path.join(Root, File), Info.MetaFile.Dir) + if File in SrcList: + continue + SrcList.append(File) + os.chdir(Cwd) + + if 'BUILD' in Info.BuildOption and Info.BuildOption['BUILD']['FLAGS'].find('-c') > -1: + CompatibleMode = True + else: + CompatibleMode = False + + # + # -s is a temporary option dedicated for building .UNI files with ISO 639-2 lanauge codes of EDK Shell in EDK2 + # + if 'BUILD' in Info.BuildOption and Info.BuildOption['BUILD']['FLAGS'].find('-s') > -1: + if CompatibleMode: + EdkLogger.error("build", AUTOGEN_ERROR, + "-c and -s build options should be used exclusively", + ExtraData="[%s]" % str(Info)) + ShellMode = True + else: + ShellMode = False + + Header, Code = GetStringFiles(Info.UnicodeFileList, SrcList, IncList, ['.uni', '.inf'], Info.Name, CompatibleMode, ShellMode) + AutoGenC.Append("\n//\n//Unicode String Pack Definition\n//\n") + AutoGenC.Append(Code) + AutoGenC.Append("\n") + AutoGenH.Append("\n//\n//Unicode String ID\n//\n") + AutoGenH.Append(Header) + AutoGenH.Append("\n#define STRING_ARRAY_NAME %sStrings\n" % Info.Name) + os.chdir(WorkingDir) + +## Create common code +# +# @param Info The ModuleAutoGen object +# @param AutoGenC The TemplateString object for C code +# @param AutoGenH The TemplateString object for header file +# +def CreateHeaderCode(Info, AutoGenC, AutoGenH): + # file header + AutoGenH.Append(gAutoGenHeaderString.Replace({'FileName':'AutoGen.h'})) + # header file Prologue + AutoGenH.Append(gAutoGenHPrologueString.Replace({'File':'AUTOGENH','Guid':Info.Guid.replace('-','_')})) + if Info.AutoGenVersion >= 0x00010005: + # specification macros + AutoGenH.Append(gSpecificationString.Replace({'SpecificationName':Info.Specification.keys(), + 'SpecificationValue':Info.Specification.values()})) + # header files includes + AutoGenH.Append("#include <%s>\n" % gBasicHeaderFile) + if Info.ModuleType in gModuleTypeHeaderFile \ + and gModuleTypeHeaderFile[Info.ModuleType][0] != gBasicHeaderFile: + AutoGenH.Append("#include <%s>\n" % gModuleTypeHeaderFile[Info.ModuleType][0]) + AutoGenH.Append('\nextern GUID gEfiCallerIdGuid;\n\n') + + if Info.IsLibrary: + return + + AutoGenH.Append("#define EFI_CALLER_ID_GUID \\\n %s\n" % GuidStringToGuidStructureString(Info.Guid)) + + if Info.IsLibrary: + return + # C file header + AutoGenC.Append(gAutoGenHeaderString.Replace({'FileName':'AutoGen.c'})) + if Info.AutoGenVersion >= 0x00010005: + # C file header files includes + if Info.ModuleType in gModuleTypeHeaderFile: + for Inc in gModuleTypeHeaderFile[Info.ModuleType]: + AutoGenC.Append("#include <%s>\n" % Inc) + else: + AutoGenC.Append("#include <%s>\n" % gBasicHeaderFile) + + # + # Publish the CallerId Guid + # + AutoGenC.Append('\nGLOBAL_REMOVE_IF_UNREFERENCED GUID gEfiCallerIdGuid = %s;\n' % GuidStringToGuidStructureString(Info.Guid)) + +## Create common code for header file +# +# @param Info The ModuleAutoGen object +# @param AutoGenC The TemplateString object for C code +# @param AutoGenH The TemplateString object for header file +# +def CreateFooterCode(Info, AutoGenC, AutoGenH): + AutoGenH.Append(gAutoGenHEpilogueString) + +## Create code for a module +# +# @param Info The ModuleAutoGen object +# @param AutoGenC The TemplateString object for C code +# @param AutoGenH The TemplateString object for header file +# +def CreateCode(Info, AutoGenC, AutoGenH, StringH): + CreateHeaderCode(Info, AutoGenC, AutoGenH) + + if Info.AutoGenVersion >= 0x00010005: + CreateGuidDefinitionCode(Info, AutoGenC, AutoGenH) + CreateProtocolDefinitionCode(Info, AutoGenC, AutoGenH) + CreatePpiDefinitionCode(Info, AutoGenC, AutoGenH) + CreatePcdCode(Info, AutoGenC, AutoGenH) + CreateLibraryConstructorCode(Info, AutoGenC, AutoGenH) + CreateLibraryDestructorCode(Info, AutoGenC, AutoGenH) + CreateModuleEntryPointCode(Info, AutoGenC, AutoGenH) + CreateModuleUnloadImageCode(Info, AutoGenC, AutoGenH) + + if Info.UnicodeFileList: + FileName = "%sStrDefs.h" % Info.Name + StringH.Append(gAutoGenHeaderString.Replace({'FileName':FileName})) + StringH.Append(gAutoGenHPrologueString.Replace({'File':'STRDEFS', 'Guid':Info.Guid.replace('-','_')})) + CreateUnicodeStringCode(Info, AutoGenC, StringH) + StringH.Append("\n#endif\n") + AutoGenH.Append('#include "%s"\n' % FileName) + + CreateFooterCode(Info, AutoGenC, AutoGenH) + + # no generation of AutoGen.c for R8 modules without unicode file + if Info.AutoGenVersion < 0x00010005 and len(Info.UnicodeFileList) == 0: + AutoGenC.String = '' + +## Create the code file +# +# @param FilePath The path of code file +# @param Content The content of code file +# +# @retval True If file content is changed or file doesn't exist +# @retval False If the file exists and the content is not changed +# +def Generate(FilePath, Content): + return SaveFileOnChange(FilePath, Content, False) + diff --git a/BaseTools/Source/Python/AutoGen/GenDepex.py b/BaseTools/Source/Python/AutoGen/GenDepex.py new file mode 100644 index 0000000000..a3d07b83f2 --- /dev/null +++ b/BaseTools/Source/Python/AutoGen/GenDepex.py @@ -0,0 +1,441 @@ +## @file +# This file is used to generate DEPEX file for module's dependency expression +# +# Copyright (c) 2007, 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 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 sys +import os +import re +import traceback + +from StringIO import StringIO +from struct import pack +from Common.BuildToolError import * +from Common.Misc import SaveFileOnChange +from Common.Misc import GuidStructureStringToGuidString +from Common import EdkLogger as EdkLogger + + +## Regular expression for matching "DEPENDENCY_START ... DEPENDENCY_END" +gStartClosePattern = re.compile(".*DEPENDENCY_START(.+)DEPENDENCY_END.*", re.S) + +## Mapping between module type and EFI phase +gType2Phase = { + "BASE" : None, + "SEC" : "PEI", + "PEI_CORE" : "PEI", + "PEIM" : "PEI", + "DXE_CORE" : "DXE", + "DXE_DRIVER" : "DXE", + "DXE_SMM_DRIVER" : "DXE", + "DXE_RUNTIME_DRIVER": "DXE", + "DXE_SAL_DRIVER" : "DXE", + "UEFI_DRIVER" : "DXE", + "UEFI_APPLICATION" : "DXE", + "SMM_DRIVER" : "DXE", +} + +## Convert dependency expression string into EFI internal representation +# +# DependencyExpression class is used to parse dependency expression string and +# convert it into its binary form. +# +class DependencyExpression: + + ArchProtocols = set([ + '665e3ff6-46cc-11d4-9a38-0090273fc14d', # 'gEfiBdsArchProtocolGuid' + '26baccb1-6f42-11d4-bce7-0080c73c8881', # 'gEfiCpuArchProtocolGuid' + '26baccb2-6f42-11d4-bce7-0080c73c8881', # 'gEfiMetronomeArchProtocolGuid' + '1da97072-bddc-4b30-99f1-72a0b56fff2a', # 'gEfiMonotonicCounterArchProtocolGuid' + '27cfac87-46cc-11d4-9a38-0090273fc14d', # 'gEfiRealTimeClockArchProtocolGuid' + '27cfac88-46cc-11d4-9a38-0090273fc14d', # 'gEfiResetArchProtocolGuid' + 'b7dfb4e1-052f-449f-87be-9818fc91b733', # 'gEfiRuntimeArchProtocolGuid' + 'a46423e3-4617-49f1-b9ff-d1bfa9115839', # 'gEfiSecurityArchProtocolGuid' + '26baccb3-6f42-11d4-bce7-0080c73c8881', # 'gEfiTimerArchProtocolGuid' + '6441f818-6362-4e44-b570-7dba31dd2453', # 'gEfiVariableWriteArchProtocolGuid' + '1e5668e2-8481-11d4-bcf1-0080c73c8881', # 'gEfiVariableArchProtocolGuid' + '665e3ff5-46cc-11d4-9a38-0090273fc14d' # 'gEfiWatchdogTimerArchProtocolGuid' + ] + ) + + OpcodePriority = { + "AND" : 1, + "OR" : 1, + "NOT" : 2, + # "SOR" : 9, + # "BEFORE": 9, + # "AFTER" : 9, + } + + Opcode = { + "PEI" : { + "PUSH" : 0x02, + "AND" : 0x03, + "OR" : 0x04, + "NOT" : 0x05, + "TRUE" : 0x06, + "FALSE" : 0x07, + "END" : 0x08 + }, + + "DXE" : { + "BEFORE": 0x00, + "AFTER" : 0x01, + "PUSH" : 0x02, + "AND" : 0x03, + "OR" : 0x04, + "NOT" : 0x05, + "TRUE" : 0x06, + "FALSE" : 0x07, + "END" : 0x08, + "SOR" : 0x09 + } + } + + # all supported op codes and operands + SupportedOpcode = ["BEFORE", "AFTER", "PUSH", "AND", "OR", "NOT", "END", "SOR"] + SupportedOperand = ["TRUE", "FALSE"] + + OpcodeWithSingleOperand = ['NOT', 'BEFORE', 'AFTER'] + OpcodeWithTwoOperand = ['AND', 'OR'] + + # op code that should not be the last one + NonEndingOpcode = ["AND", "OR", "NOT", 'SOR'] + # op code must not present at the same time + ExclusiveOpcode = ["BEFORE", "AFTER"] + # op code that should be the first one if it presents + AboveAllOpcode = ["SOR", "BEFORE", "AFTER"] + + # + # open and close brace must be taken as individual tokens + # + TokenPattern = re.compile("(\(|\)|\{[^{}]+\{?[^{}]+\}?[ ]*\}|\w+)") + + ## Constructor + # + # @param Expression The list or string of dependency expression + # @param ModuleType The type of the module using the dependency expression + # + def __init__(self, Expression, ModuleType, Optimize=False): + self.ModuleType = ModuleType + self.Phase = gType2Phase[ModuleType] + if type(Expression) == type([]): + self.ExpressionString = " ".join(Expression) + self.TokenList = Expression + else: + self.ExpressionString = Expression + self.GetExpressionTokenList() + + self.PostfixNotation = [] + self.OpcodeList = [] + + self.GetPostfixNotation() + self.ValidateOpcode() + + EdkLogger.debug(EdkLogger.DEBUG_8, repr(self)) + if Optimize: + self.Optimize() + EdkLogger.debug(EdkLogger.DEBUG_8, "\n Optimized: " + repr(self)) + + def __str__(self): + return " ".join(self.TokenList) + + def __repr__(self): + WellForm = '' + for Token in self.PostfixNotation: + if Token in self.SupportedOpcode: + WellForm += "\n " + Token + else: + WellForm += ' ' + Token + return WellForm + + ## Split the expression string into token list + def GetExpressionTokenList(self): + self.TokenList = self.TokenPattern.findall(self.ExpressionString) + + ## Convert token list into postfix notation + def GetPostfixNotation(self): + Stack = [] + LastToken = '' + for Token in self.TokenList: + if Token == "(": + if LastToken not in self.SupportedOpcode + ['(', '', None]: + EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operator before open parentheses", + ExtraData="Near %s" % LastToken) + Stack.append(Token) + elif Token == ")": + if '(' not in Stack: + EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: mismatched parentheses", + ExtraData=str(self)) + elif LastToken in self.SupportedOpcode + ['', None]: + EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operand before close parentheses", + ExtraData="Near %s" % LastToken) + while len(Stack) > 0: + if Stack[-1] == '(': + Stack.pop() + break + self.PostfixNotation.append(Stack.pop()) + elif Token in self.OpcodePriority: + if Token == "NOT": + if LastToken not in self.SupportedOpcode + ['(', '', None]: + EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operator before NOT", + ExtraData="Near %s" % LastToken) + elif LastToken in self.SupportedOpcode + ['(', '', None]: + EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operand before " + Token, + ExtraData="Near %s" % LastToken) + + while len(Stack) > 0: + if Stack[-1] == "(" or self.OpcodePriority[Token] >= self.OpcodePriority[Stack[-1]]: + break + self.PostfixNotation.append(Stack.pop()) + Stack.append(Token) + self.OpcodeList.append(Token) + else: + if Token not in self.SupportedOpcode: + # not OP, take it as GUID + if LastToken not in self.SupportedOpcode + ['(', '', None]: + EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operator before %s" % Token, + ExtraData="Near %s" % LastToken) + if len(self.OpcodeList) == 0 or self.OpcodeList[-1] not in self.ExclusiveOpcode: + if Token not in self.SupportedOperand: + self.PostfixNotation.append("PUSH") + # check if OP is valid in this phase + elif Token in self.Opcode[self.Phase]: + if Token == "END": + break + self.OpcodeList.append(Token) + else: + EdkLogger.error("GenDepex", PARSER_ERROR, + "Opcode=%s doesn't supported in %s stage " % (Token, self.Phase), + ExtraData=str(self)) + self.PostfixNotation.append(Token) + LastToken = Token + + # there should not be parentheses in Stack + if '(' in Stack or ')' in Stack: + EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: mismatched parentheses", + ExtraData=str(self)) + while len(Stack) > 0: + self.PostfixNotation.append(Stack.pop()) + if self.PostfixNotation[-1] != 'END': + self.PostfixNotation.append("END") + + ## Validate the dependency expression + def ValidateOpcode(self): + for Op in self.AboveAllOpcode: + if Op in self.PostfixNotation: + if Op != self.PostfixNotation[0]: + EdkLogger.error("GenDepex", PARSER_ERROR, "%s should be the first opcode in the expression" % Op, + ExtraData=str(self)) + if len(self.PostfixNotation) < 3: + EdkLogger.error("GenDepex", PARSER_ERROR, "Missing operand for %s" % Op, + ExtraData=str(self)) + for Op in self.ExclusiveOpcode: + if Op in self.OpcodeList: + if len(self.OpcodeList) > 1: + EdkLogger.error("GenDepex", PARSER_ERROR, "%s should be the only opcode in the expression" % Op, + ExtraData=str(self)) + if len(self.PostfixNotation) < 3: + EdkLogger.error("GenDepex", PARSER_ERROR, "Missing operand for %s" % Op, + ExtraData=str(self)) + if self.TokenList[-1] != 'END' and self.TokenList[-1] in self.NonEndingOpcode: + EdkLogger.error("GenDepex", PARSER_ERROR, "Extra %s at the end of the dependency expression" % self.TokenList[-1], + ExtraData=str(self)) + if self.TokenList[-1] == 'END' and self.TokenList[-2] in self.NonEndingOpcode: + EdkLogger.error("GenDepex", PARSER_ERROR, "Extra %s at the end of the dependency expression" % self.TokenList[-2], + ExtraData=str(self)) + if "END" in self.TokenList and "END" != self.TokenList[-1]: + EdkLogger.error("GenDepex", PARSER_ERROR, "Extra expressions after END", + ExtraData=str(self)) + + ## Simply optimize the dependency expression by removing duplicated operands + def Optimize(self): + ValidOpcode = list(set(self.OpcodeList)) + if len(ValidOpcode) != 1 or ValidOpcode[0] not in ['AND', 'OR']: + return + Op = ValidOpcode[0] + NewOperand = [] + AllOperand = set() + for Token in self.PostfixNotation: + if Token in self.SupportedOpcode or Token in NewOperand: + continue + AllOperand.add(Token) + if Token == 'TRUE': + if Op == 'AND': + continue + else: + NewOperand.append(Token) + break + elif Token == 'FALSE': + if Op == 'OR': + continue + else: + NewOperand.append(Token) + break + NewOperand.append(Token) + + # don't generate depex if only TRUE operand left + if self.ModuleType == 'PEIM' and len(NewOperand) == 1 and NewOperand[0] == 'TRUE': + self.PostfixNotation = [] + return + + # don't generate depex if all operands are architecture protocols + if self.ModuleType in ['UEFI_DRIVER', 'DXE_DRIVER', 'DXE_RUNTIME_DRIVER', 'DXE_SAL_DRIVER', 'DXE_SMM_DRIVER'] and \ + Op == 'AND' and \ + self.ArchProtocols == set([GuidStructureStringToGuidString(Guid) for Guid in AllOperand]): + self.PostfixNotation = [] + return + + if len(NewOperand) == 0: + self.TokenList = list(AllOperand) + else: + self.TokenList = [] + while True: + self.TokenList.append(NewOperand.pop(0)) + if NewOperand == []: + break + self.TokenList.append(Op) + self.PostfixNotation = [] + self.GetPostfixNotation() + + + ## Convert a GUID value in C structure format into its binary form + # + # @param Guid The GUID value in C structure format + # + # @retval array The byte array representing the GUID value + # + def GetGuidValue(self, Guid): + GuidValueString = Guid.replace("{", "").replace("}", "").replace(" ", "") + GuidValueList = GuidValueString.split(",") + if len(GuidValueList) != 11: + EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid GUID value string or opcode: %s" % Guid) + return pack("1I2H8B", *(int(value, 16) for value in GuidValueList)) + + ## Save the binary form of dependency expression in file + # + # @param File The path of file. If None is given, put the data on console + # + # @retval True If the file doesn't exist or file is changed + # @retval False If file exists and is not changed. + # + def Generate(self, File=None): + Buffer = StringIO() + if len(self.PostfixNotation) == 0: + return False + + for Item in self.PostfixNotation: + if Item in self.Opcode[self.Phase]: + Buffer.write(pack("B", self.Opcode[self.Phase][Item])) + elif Item in self.SupportedOpcode: + EdkLogger.error("GenDepex", FORMAT_INVALID, + "Opcode [%s] is not expected in %s phase" % (Item, self.Phase), + ExtraData=self.ExpressionString) + else: + Buffer.write(self.GetGuidValue(Item)) + + FilePath = "" + FileChangeFlag = True + if File == None: + sys.stdout.write(Buffer.getvalue()) + FilePath = "STDOUT" + else: + FileChangeFlag = SaveFileOnChange(File, Buffer.getvalue(), True) + + Buffer.close() + return FileChangeFlag + +versionNumber = "0.04" +__version__ = "%prog Version " + versionNumber +__copyright__ = "Copyright (c) 2007-2008, Intel Corporation All rights reserved." +__usage__ = "%prog [options] [dependency_expression_file]" + +## Parse command line options +# +# @retval OptionParser +# +def GetOptions(): + from optparse import OptionParser + + Parser = OptionParser(description=__copyright__, version=__version__, usage=__usage__) + + Parser.add_option("-o", "--output", dest="OutputFile", default=None, metavar="FILE", + help="Specify the name of depex file to be generated") + Parser.add_option("-t", "--module-type", dest="ModuleType", default=None, + help="The type of module for which the dependency expression serves") + Parser.add_option("-e", "--dependency-expression", dest="Expression", default="", + help="The string of dependency expression. If this option presents, the input file will be ignored.") + Parser.add_option("-m", "--optimize", dest="Optimize", default=False, action="store_true", + help="Do some simple optimization on the expression.") + Parser.add_option("-v", "--verbose", dest="verbose", default=False, action="store_true", + help="build with verbose information") + Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.") + Parser.add_option("-q", "--quiet", dest="quiet", default=False, action="store_true", + help="build with little information") + + return Parser.parse_args() + + +## Entrance method +# +# @retval 0 Tool was successful +# @retval 1 Tool failed +# +def Main(): + EdkLogger.Initialize() + Option, Input = GetOptions() + + # Set log level + if Option.quiet: + EdkLogger.SetLevel(EdkLogger.QUIET) + elif Option.verbose: + EdkLogger.SetLevel(EdkLogger.VERBOSE) + elif Option.debug != None: + EdkLogger.SetLevel(Option.debug + 1) + else: + EdkLogger.SetLevel(EdkLogger.INFO) + + try: + if Option.ModuleType == None or Option.ModuleType not in gType2Phase: + EdkLogger.error("GenDepex", OPTION_MISSING, "Module type is not specified or supported") + + DxsFile = '' + if len(Input) > 0 and Option.Expression == "": + DxsFile = Input[0] + DxsString = open(DxsFile, 'r').read().replace("\n", " ").replace("\r", " ") + DxsString = gStartClosePattern.sub("\\1", DxsString) + elif Option.Expression != "": + if Option.Expression[0] == '"': + DxsString = Option.Expression[1:-1] + else: + DxsString = Option.Expression + else: + EdkLogger.error("GenDepex", OPTION_MISSING, "No expression string or file given") + + Dpx = DependencyExpression(DxsString, Option.ModuleType, Option.Optimize) + if Option.OutputFile != None: + Dpx.Generate(Option.OutputFile) + else: + Dpx.Generate() + except BaseException, X: + EdkLogger.quiet("") + if Option != None and Option.debug != None: + EdkLogger.quiet(traceback.format_exc()) + else: + EdkLogger.quiet(str(X)) + return 1 + + return 0 + +if __name__ == '__main__': + sys.exit(Main()) + diff --git a/BaseTools/Source/Python/AutoGen/GenMake.py b/BaseTools/Source/Python/AutoGen/GenMake.py new file mode 100644 index 0000000000..f689a8692d --- /dev/null +++ b/BaseTools/Source/Python/AutoGen/GenMake.py @@ -0,0 +1,1389 @@ +## @file +# Create makefile for MS nmake and GNU make +# +# Copyright (c) 2007, 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 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 string +import re +import os.path as path + +from Common.BuildToolError import * +from Common.Misc import * +from Common.String import * +from BuildEngine import * +import Common.GlobalData as GlobalData + +## Regular expression for finding header file inclusions +gIncludePattern = re.compile(r"^[ \t]*#[ \t]*include(?:[ \t]*(?:\\(?:\r\n|\r|\n))*[ \t]*)*(?:[\"<][ \t]*)([\w.\\/]+)(?:[ \t]*[\">])", re.MULTILINE|re.UNICODE) + +## Regular expression for matching macro used in header file inclusion +gMacroPattern = re.compile("([_A-Z][_A-Z0-9]*)[ \t]*\((.+)\)", re.UNICODE) + +## pattern for include style in R8.x code +gProtocolDefinition = "Protocol/%(HeaderKey)s/%(HeaderKey)s.h" +gGuidDefinition = "Guid/%(HeaderKey)s/%(HeaderKey)s.h" +gArchProtocolDefinition = "ArchProtocol/%(HeaderKey)s/%(HeaderKey)s.h" +gPpiDefinition = "Ppi/%(HeaderKey)s/%(HeaderKey)s.h" +gIncludeMacroConversion = { + "EFI_PROTOCOL_DEFINITION" : gProtocolDefinition, + "EFI_GUID_DEFINITION" : gGuidDefinition, + "EFI_ARCH_PROTOCOL_DEFINITION" : gArchProtocolDefinition, + "EFI_PROTOCOL_PRODUCER" : gProtocolDefinition, + "EFI_PROTOCOL_CONSUMER" : gProtocolDefinition, + "EFI_PROTOCOL_DEPENDENCY" : gProtocolDefinition, + "EFI_ARCH_PROTOCOL_PRODUCER" : gArchProtocolDefinition, + "EFI_ARCH_PROTOCOL_CONSUMER" : gArchProtocolDefinition, + "EFI_ARCH_PROTOCOL_DEPENDENCY" : gArchProtocolDefinition, + "EFI_PPI_DEFINITION" : gPpiDefinition, + "EFI_PPI_PRODUCER" : gPpiDefinition, + "EFI_PPI_CONSUMER" : gPpiDefinition, + "EFI_PPI_DEPENDENCY" : gPpiDefinition, +} + +## default makefile type +gMakeType = "" +if sys.platform == "win32": + gMakeType = "nmake" +else: + gMakeType = "gmake" + + +## BuildFile class +# +# This base class encapsules build file and its generation. It uses template to generate +# the content of build file. The content of build file will be got from AutoGen objects. +# +class BuildFile(object): + ## template used to generate the build file (i.e. makefile if using make) + _TEMPLATE_ = TemplateString('') + + _DEFAULT_FILE_NAME_ = "Makefile" + + ## default file name for each type of build file + _FILE_NAME_ = { + "nmake" : "Makefile", + "gmake" : "GNUmakefile" + } + + ## Fixed header string for makefile + _MAKEFILE_HEADER = '''# +# DO NOT EDIT +# This file is auto-generated by build utility +# +# Module Name: +# +# %s +# +# Abstract: +# +# Auto-generated makefile for building modules, libraries or platform +# + ''' + + ## Header string for each type of build file + _FILE_HEADER_ = { + "nmake" : _MAKEFILE_HEADER % _FILE_NAME_["nmake"], + "gmake" : _MAKEFILE_HEADER % _FILE_NAME_["gmake"] + } + + ## shell commands which can be used in build file in the form of macro + # $(CP) copy file command + # $(MV) move file command + # $(RM) remove file command + # $(MD) create dir command + # $(RD) remove dir command + # + _SHELL_CMD_ = { + "nmake" : { + "CP" : "copy /y", + "MV" : "move /y", + "RM" : "del /f /q", + "MD" : "mkdir", + "RD" : "rmdir /s /q", + }, + + "gmake" : { + "CP" : "cp -f", + "MV" : "mv -f", + "RM" : "rm -f", + "MD" : "mkdir -p", + "RD" : "rm -r -f", + } + } + + ## directory separator + _SEP_ = { + "nmake" : "\\", + "gmake" : "/" + } + + ## directory creation template + _MD_TEMPLATE_ = { + "nmake" : 'if not exist %(dir)s $(MD) %(dir)s', + "gmake" : "$(MD) %(dir)s" + } + + ## directory removal template + _RD_TEMPLATE_ = { + "nmake" : 'if exist %(dir)s $(RD) %(dir)s', + "gmake" : "$(RD) %(dir)s" + } + + _CD_TEMPLATE_ = { + "nmake" : 'if exist %(dir)s cd %(dir)s', + "gmake" : "test -e %(dir)s && cd %(dir)s" + } + + _MAKE_TEMPLATE_ = { + "nmake" : 'if exist %(file)s "$(MAKE)" $(MAKE_FLAGS) -f %(file)s', + "gmake" : 'test -e %(file)s && "$(MAKE)" $(MAKE_FLAGS) -f %(file)s' + } + + _INCLUDE_CMD_ = { + "nmake" : '!INCLUDE', + "gmake" : "include" + } + + _INC_FLAG_ = {"MSFT" : "/I", "GCC" : "-I", "INTEL" : "-I", "RVCT" : "-I"} + + ## Constructor of BuildFile + # + # @param AutoGenObject Object of AutoGen class + # + def __init__(self, AutoGenObject): + self._AutoGenObject = AutoGenObject + self._FileType = gMakeType + + ## Create build file + # + # @param FileType Type of build file. Only nmake and gmake are supported now. + # + # @retval TRUE The build file is created or re-created successfully + # @retval FALSE The build file exists and is the same as the one to be generated + # + def Generate(self, FileType=gMakeType): + if FileType not in self._FILE_NAME_: + EdkLogger.error("build", PARAMETER_INVALID, "Invalid build type [%s]" % FileType, + ExtraData="[%s]" % str(self._AutoGenObject)) + self._FileType = FileType + FileContent = self._TEMPLATE_.Replace(self._TemplateDict) + FileName = self._FILE_NAME_[FileType] + return SaveFileOnChange(os.path.join(self._AutoGenObject.MakeFileDir, FileName), FileContent, False) + + ## Return a list of directory creation command string + # + # @param DirList The list of directory to be created + # + # @retval list The directory creation command list + # + def GetCreateDirectoryCommand(self, DirList): + return [self._MD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList] + + ## Return a list of directory removal command string + # + # @param DirList The list of directory to be removed + # + # @retval list The directory removal command list + # + def GetRemoveDirectoryCommand(self, DirList): + return [self._RD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList] + + def PlaceMacro(self, Path, MacroDefinitions={}): + if Path.startswith("$("): + return Path + else: + PathLength = len(Path) + for MacroName in MacroDefinitions: + MacroValue = MacroDefinitions[MacroName] + MacroValueLength = len(MacroValue) + if MacroValueLength <= PathLength and Path.startswith(MacroValue): + Path = "$(%s)%s" % (MacroName, Path[MacroValueLength:]) + break + return Path + +## ModuleMakefile class +# +# This class encapsules makefie and its generation for module. It uses template to generate +# the content of makefile. The content of makefile will be got from ModuleAutoGen object. +# +class ModuleMakefile(BuildFile): + ## template used to generate the makefile for module + _TEMPLATE_ = TemplateString('''\ +${makefile_header} + +# +# Platform Macro Definition +# +PLATFORM_NAME = ${platform_name} +PLATFORM_GUID = ${platform_guid} +PLATFORM_VERSION = ${platform_version} +PLATFORM_RELATIVE_DIR = ${platform_relative_directory} +PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory} +PLATFORM_OUTPUT_DIR = ${platform_output_directory} + +# +# Module Macro Definition +# +MODULE_NAME = ${module_name} +MODULE_GUID = ${module_guid} +MODULE_VERSION = ${module_version} +MODULE_TYPE = ${module_type} +MODULE_FILE = ${module_file} +MODULE_FILE_BASE_NAME = ${module_file_base_name} +BASE_NAME = $(MODULE_NAME) +MODULE_RELATIVE_DIR = ${module_relative_directory} +MODULE_DIR = $(WORKSPACE)${separator}${module_relative_directory} + +MODULE_ENTRY_POINT = ${module_entry_point} +ARCH_ENTRY_POINT = ${arch_entry_point} +IMAGE_ENTRY_POINT = ${image_entry_point} + +${BEGIN}${module_extra_defines} +${END} +# +# Build Configuration Macro Definition +# +ARCH = ${architecture} +TOOLCHAIN = ${toolchain_tag} +TOOLCHAIN_TAG = ${toolchain_tag} +TARGET = ${build_target} + +# +# Build Directory Macro Definition +# +# PLATFORM_BUILD_DIR = ${platform_build_directory} +BUILD_DIR = ${platform_build_directory} +BIN_DIR = $(BUILD_DIR)${separator}${architecture} +LIB_DIR = $(BIN_DIR) +MODULE_BUILD_DIR = ${module_build_directory} +OUTPUT_DIR = ${module_output_directory} +DEBUG_DIR = ${module_debug_directory} +DEST_DIR_OUTPUT = $(OUTPUT_DIR) +DEST_DIR_DEBUG = $(DEBUG_DIR) + +# +# Shell Command Macro +# +${BEGIN}${shell_command_code} = ${shell_command} +${END} + +# +# Tools definitions specific to this module +# +${BEGIN}${module_tool_definitions} +${END} +MAKE_FILE = ${makefile_path} + +# +# Build Macro +# +${BEGIN}${file_macro} +${END} + +COMMON_DEPS = ${BEGIN}${common_dependency_file} \\ + ${END} + +# +# Overridable Target Macro Definitions +# +FORCE_REBUILD = force_build +INIT_TARGET = init +PCH_TARGET = +BC_TARGET = ${BEGIN}${backward_compatible_target} ${END} +CODA_TARGET = ${BEGIN}${remaining_build_target} \\ + ${END} + +# +# Default target, which will build dependent libraries in addition to source files +# + +all: mbuild + + +# +# Target used when called from platform makefile, which will bypass the build of dependent libraries +# + +pbuild: $(INIT_TARGET) $(BC_TARGET) $(PCH_TARGET) $(CODA_TARGET) + +# +# ModuleTarget +# + +mbuild: $(INIT_TARGET) $(BC_TARGET) gen_libs $(PCH_TARGET) $(CODA_TARGET) + +# +# Build Target used in multi-thread build mode, which will bypass the init and gen_libs targets +# + +tbuild: $(BC_TARGET) $(PCH_TARGET) $(CODA_TARGET) + +# +# Phony target which is used to force executing commands for a target +# +force_build: +\t-@ + +# +# Target to update the FD +# + +fds: mbuild gen_fds + +# +# Initialization target: print build information and create necessary directories +# +init: info dirs + +info: +\t-@echo Building ... $(MODULE_DIR)${separator}$(MODULE_FILE) [$(ARCH)] + +dirs: +${BEGIN}\t-@${create_directory_command}\n${END} + +strdefs: +\t-@$(CP) $(DEBUG_DIR)${separator}AutoGen.h $(DEBUG_DIR)${separator}$(MODULE_NAME)StrDefs.h + +# +# GenLibsTarget +# +gen_libs: +\t${BEGIN}@"$(MAKE)" $(MAKE_FLAGS) -f ${dependent_library_build_directory}${separator}${makefile_name} +\t${END}@cd $(MODULE_BUILD_DIR) + +# +# Build Flash Device Image +# +gen_fds: +\t@"$(MAKE)" $(MAKE_FLAGS) -f $(BUILD_DIR)${separator}${makefile_name} fds +\t@cd $(MODULE_BUILD_DIR) + +# +# Individual Object Build Targets +# +${BEGIN}${file_build_target} +${END} + +# +# clean all intermediate files +# +clean: +\t${BEGIN}${clean_command} +\t${END} + +# +# clean all generated files +# +cleanall: +${BEGIN}\t${cleanall_command} +${END}\t$(RM) *.pdb *.idb > NUL 2>&1 +\t$(RM) $(BIN_DIR)${separator}$(MODULE_NAME).efi + +# +# clean all dependent libraries built +# +cleanlib: +\t${BEGIN}-@${library_build_command} cleanall +\t${END}@cd $(MODULE_BUILD_DIR)\n\n''') + + _FILE_MACRO_TEMPLATE = TemplateString("${macro_name} = ${BEGIN} \\\n ${source_file}${END}\n") + _BUILD_TARGET_TEMPLATE = TemplateString("${BEGIN}${target} : ${deps}\n${END}\t${cmd}\n") + + ## Constructor of ModuleMakefile + # + # @param ModuleAutoGen Object of ModuleAutoGen class + # + def __init__(self, ModuleAutoGen): + BuildFile.__init__(self, ModuleAutoGen) + self.PlatformInfo = self._AutoGenObject.PlatformInfo + + self.ResultFileList = [] + self.IntermediateDirectoryList = ["$(DEBUG_DIR)", "$(OUTPUT_DIR)"] + + self.SourceFileDatabase = {} # {file type : file path} + self.DestFileDatabase = {} # {file type : file path} + self.FileBuildTargetList = [] # [(src, target string)] + self.BuildTargetList = [] # [target string] + self.PendingBuildTargetList = [] # [FileBuildRule objects] + self.CommonFileDependency = [] + self.FileListMacros = {} + self.ListFileMacros = {} + + self.FileDependency = [] + self.LibraryBuildCommandList = [] + self.LibraryFileList = [] + self.LibraryMakefileList = [] + self.LibraryBuildDirectoryList = [] + self.SystemLibraryList = [] + self.Macros = sdict() + self.Macros["OUTPUT_DIR" ] = self._AutoGenObject.Macros["OUTPUT_DIR"] + self.Macros["DEBUG_DIR" ] = self._AutoGenObject.Macros["DEBUG_DIR"] + self.Macros["MODULE_BUILD_DIR"] = self._AutoGenObject.Macros["MODULE_BUILD_DIR"] + self.Macros["BIN_DIR" ] = self._AutoGenObject.Macros["BIN_DIR"] + self.Macros["BUILD_DIR" ] = self._AutoGenObject.Macros["BUILD_DIR"] + self.Macros["WORKSPACE" ] = self._AutoGenObject.Macros["WORKSPACE"] + + # Compose a dict object containing information used to do replacement in template + def _CreateTemplateDict(self): + if self._FileType not in self._SEP_: + EdkLogger.error("build", PARAMETER_INVALID, "Invalid Makefile type [%s]" % self._FileType, + ExtraData="[%s]" % str(self._AutoGenObject)) + Separator = self._SEP_[self._FileType] + + # break build if no source files and binary files are found + if len(self._AutoGenObject.SourceFileList) == 0 and len(self._AutoGenObject.BinaryFileList) == 0: + EdkLogger.error("build", AUTOGEN_ERROR, "No files to be built in module [%s, %s, %s]" + % (self._AutoGenObject.BuildTarget, self._AutoGenObject.ToolChain, self._AutoGenObject.Arch), + ExtraData="[%s]" % str(self._AutoGenObject)) + + # convert dependent libaries to build command + self.ProcessDependentLibrary() + if len(self._AutoGenObject.Module.ModuleEntryPointList) > 0: + ModuleEntryPoint = self._AutoGenObject.Module.ModuleEntryPointList[0] + else: + ModuleEntryPoint = "_ModuleEntryPoint" + + # Intel EBC compiler enforces EfiMain + if self._AutoGenObject.AutoGenVersion < 0x00010005 and self._AutoGenObject.Arch == "EBC": + ArchEntryPoint = "EfiMain" + else: + ArchEntryPoint = ModuleEntryPoint + + if self._AutoGenObject.Arch == "EBC": + # EBC compiler always use "EfiStart" as entry point. Only applies to R9 modules + ImageEntryPoint = "EfiStart" + elif self._AutoGenObject.AutoGenVersion < 0x00010005: + # R8 modules use entry point specified in INF file + ImageEntryPoint = ModuleEntryPoint + else: + # R9 modules always use "_ModuleEntryPoint" as entry point + ImageEntryPoint = "_ModuleEntryPoint" + + # tools definitions + ToolsDef = [] + IncPrefix = self._INC_FLAG_[self._AutoGenObject.ToolChainFamily] + for Tool in self._AutoGenObject.BuildOption: + for Attr in self._AutoGenObject.BuildOption[Tool]: + Value = self._AutoGenObject.BuildOption[Tool][Attr] + if Attr == "FAMILY": + continue + elif Attr == "PATH": + ToolsDef.append("%s = %s" % (Tool, Value)) + else: + # Don't generate MAKE_FLAGS in makefile. It's put in environment variable. + if Tool == "MAKE": + continue + # Remove duplicated include path, if any + if Attr == "FLAGS": + Value = RemoveDupOption(Value, IncPrefix, self._AutoGenObject.IncludePathList) + ToolsDef.append("%s_%s = %s" % (Tool, Attr, Value)) + ToolsDef.append("") + + # convert source files and binary files to build targets + self.ResultFileList = [str(T.Target) for T in self._AutoGenObject.CodaTargetList] + if len(self.ResultFileList) == 0: + EdkLogger.error("build", AUTOGEN_ERROR, "Nothing to build", + ExtraData="[%s]" % str(self._AutoGenObject)) + + self.ProcessBuildTargetList() + + # Generate macros used to represent input files + FileMacroList = [] # macro name = file list + for FileListMacro in self.FileListMacros: + FileMacro = self._FILE_MACRO_TEMPLATE.Replace( + { + "macro_name" : FileListMacro, + "source_file" : self.FileListMacros[FileListMacro] + } + ) + FileMacroList.append(FileMacro) + + # INC_LIST is special + FileMacro = "" + IncludePathList = [] + for P in self._AutoGenObject.IncludePathList: + IncludePathList.append(IncPrefix+self.PlaceMacro(P, self.Macros)) + if FileBuildRule.INC_LIST_MACRO in self.ListFileMacros: + self.ListFileMacros[FileBuildRule.INC_LIST_MACRO].append(IncPrefix+P) + FileMacro += self._FILE_MACRO_TEMPLATE.Replace( + { + "macro_name" : "INC", + "source_file" : IncludePathList + } + ) + FileMacroList.append(FileMacro) + + # Generate macros used to represent files containing list of input files + for ListFileMacro in self.ListFileMacros: + ListFileName = os.path.join(self._AutoGenObject.OutputDir, "%s.lst" % ListFileMacro.lower()[:len(ListFileMacro)-5]) + FileMacroList.append("%s = %s" % (ListFileMacro, ListFileName)) + SaveFileOnChange( + ListFileName, + "\n".join(self.ListFileMacros[ListFileMacro]), + False + ) + + # R8 modules need StrDefs.h for string ID + #if self._AutoGenObject.AutoGenVersion < 0x00010005 and len(self._AutoGenObject.UnicodeFileList) > 0: + # BcTargetList = ['strdefs'] + #else: + # BcTargetList = [] + BcTargetList = [] + + MakefileName = self._FILE_NAME_[self._FileType] + LibraryMakeCommandList = [] + for D in self.LibraryBuildDirectoryList: + Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join(D, MakefileName)} + LibraryMakeCommandList.append(Command) + + MakefileTemplateDict = { + "makefile_header" : self._FILE_HEADER_[self._FileType], + "makefile_path" : os.path.join("$(MODULE_BUILD_DIR)", MakefileName), + "makefile_name" : MakefileName, + "platform_name" : self.PlatformInfo.Name, + "platform_guid" : self.PlatformInfo.Guid, + "platform_version" : self.PlatformInfo.Version, + "platform_relative_directory": self.PlatformInfo.SourceDir, + "platform_output_directory" : self.PlatformInfo.OutputDir, + + "module_name" : self._AutoGenObject.Name, + "module_guid" : self._AutoGenObject.Guid, + "module_version" : self._AutoGenObject.Version, + "module_type" : self._AutoGenObject.ModuleType, + "module_file" : self._AutoGenObject.MetaFile.Name, + "module_file_base_name" : self._AutoGenObject.MetaFile.BaseName, + "module_relative_directory" : self._AutoGenObject.SourceDir, + "module_extra_defines" : ["%s = %s" % (k, v) for k,v in self._AutoGenObject.Module.Defines.iteritems()], + + "architecture" : self._AutoGenObject.Arch, + "toolchain_tag" : self._AutoGenObject.ToolChain, + "build_target" : self._AutoGenObject.BuildTarget, + + "platform_build_directory" : self.PlatformInfo.BuildDir, + "module_build_directory" : self._AutoGenObject.BuildDir, + "module_output_directory" : self._AutoGenObject.OutputDir, + "module_debug_directory" : self._AutoGenObject.DebugDir, + + "separator" : Separator, + "module_tool_definitions" : ToolsDef, + + "shell_command_code" : self._SHELL_CMD_[self._FileType].keys(), + "shell_command" : self._SHELL_CMD_[self._FileType].values(), + + "module_entry_point" : ModuleEntryPoint, + "image_entry_point" : ImageEntryPoint, + "arch_entry_point" : ArchEntryPoint, + "remaining_build_target" : self.ResultFileList, + "common_dependency_file" : self.CommonFileDependency, + "create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList), + "clean_command" : self.GetRemoveDirectoryCommand(["$(OUTPUT_DIR)"]), + "cleanall_command" : self.GetRemoveDirectoryCommand(["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]), + "dependent_library_build_directory" : self.LibraryBuildDirectoryList, + "library_build_command" : LibraryMakeCommandList, + "file_macro" : FileMacroList, + "file_build_target" : self.BuildTargetList, + "backward_compatible_target": BcTargetList, + } + + return MakefileTemplateDict + + def ProcessBuildTargetList(self): + # + # Search dependency file list for each source file + # + ForceIncludedFile = [] + for File in self._AutoGenObject.AutoGenFileList: + if File.Ext == '.h': + ForceIncludedFile.append(File) + SourceFileList = [] + for Target in self._AutoGenObject.IntroTargetList: + SourceFileList.extend(Target.Inputs) + + self.FileDependency = self.GetFileDependency( + SourceFileList, + ForceIncludedFile, + self._AutoGenObject.IncludePathList + ) + DepSet = None + for File in self.FileDependency: + if not self.FileDependency[File]: + self.FileDependency[File] = ['$(FORCE_REBUILD)'] + continue + # skip non-C files + if File.Ext not in [".c", ".C"] or File.Name == "AutoGen.c": + continue + elif DepSet == None: + DepSet = set(self.FileDependency[File]) + else: + DepSet &= set(self.FileDependency[File]) + # in case nothing in SourceFileList + if DepSet == None: + DepSet = set() + # + # Extract comman files list in the dependency files + # + for File in DepSet: + self.CommonFileDependency.append(self.PlaceMacro(File.Path, self.Macros)) + + for File in self.FileDependency: + # skip non-C files + if File.Ext not in [".c", ".C"] or File.Name == "AutoGen.c": + continue + NewDepSet = set(self.FileDependency[File]) + NewDepSet -= DepSet + self.FileDependency[File] = ["$(COMMON_DEPS)"] + list(NewDepSet) + + # Convert target description object to target string in makefile + for Type in self._AutoGenObject.Targets: + for T in self._AutoGenObject.Targets[Type]: + # Generate related macros if needed + if T.GenFileListMacro and T.FileListMacro not in self.FileListMacros: + self.FileListMacros[T.FileListMacro] = [] + if T.GenListFile and T.ListFileMacro not in self.ListFileMacros: + self.ListFileMacros[T.ListFileMacro] = [] + if T.GenIncListFile and T.IncListFileMacro not in self.ListFileMacros: + self.ListFileMacros[T.IncListFileMacro] = [] + + Deps = [] + # Add force-dependencies + for Dep in T.Dependencies: + Deps.append(self.PlaceMacro(str(Dep), self.Macros)) + # Add inclusion-dependencies + if len(T.Inputs) == 1 and T.Inputs[0] in self.FileDependency: + for F in self.FileDependency[T.Inputs[0]]: + Deps.append(self.PlaceMacro(str(F), self.Macros)) + # Add source-dependencies + for F in T.Inputs: + NewFile = self.PlaceMacro(str(F), self.Macros) + # In order to use file list macro as dependency + if T.GenListFile: + self.ListFileMacros[T.ListFileMacro].append(str(F)) + self.FileListMacros[T.FileListMacro].append(NewFile) + elif T.GenFileListMacro: + self.FileListMacros[T.FileListMacro].append(NewFile) + else: + Deps.append(NewFile) + + # Use file list macro as dependency + if T.GenFileListMacro: + Deps.append("$(%s)" % T.FileListMacro) + + TargetDict = { + "target" : self.PlaceMacro(T.Target.Path, self.Macros), + "cmd" : "\n\t".join(T.Commands), + "deps" : Deps + } + self.BuildTargetList.append(self._BUILD_TARGET_TEMPLATE.Replace(TargetDict)) + + ## For creating makefile targets for dependent libraries + def ProcessDependentLibrary(self): + for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList: + self.LibraryBuildDirectoryList.append(self.PlaceMacro(LibraryAutoGen.BuildDir, self.Macros)) + + ## Return a list containing source file's dependencies + # + # @param FileList The list of source files + # @param ForceInculeList The list of files which will be included forcely + # @param SearchPathList The list of search path + # + # @retval dict The mapping between source file path and its dependencies + # + def GetFileDependency(self, FileList, ForceInculeList, SearchPathList): + Dependency = {} + for F in FileList: + Dependency[F] = self.GetDependencyList(F, ForceInculeList, SearchPathList) + return Dependency + + ## Find dependencies for one source file + # + # By searching recursively "#include" directive in file, find out all the + # files needed by given source file. The dependecies will be only searched + # in given search path list. + # + # @param File The source file + # @param ForceInculeList The list of files which will be included forcely + # @param SearchPathList The list of search path + # + # @retval list The list of files the given source file depends on + # + def GetDependencyList(self, File, ForceList, SearchPathList): + EdkLogger.debug(EdkLogger.DEBUG_1, "Try to get dependency files for %s" % File) + FileStack = [File] + ForceList + DependencySet = set() + MacroUsedByIncludedFile = False + + if self._AutoGenObject.Arch not in gDependencyDatabase: + gDependencyDatabase[self._AutoGenObject.Arch] = {} + DepDb = gDependencyDatabase[self._AutoGenObject.Arch] + + while len(FileStack) > 0: + F = FileStack.pop() + + CurrentFileDependencyList = [] + if F in DepDb: + CurrentFileDependencyList = DepDb[F] + for Dep in CurrentFileDependencyList: + if Dep not in FileStack and Dep not in DependencySet: + FileStack.append(Dep) + else: + try: + Fd = open(F.Path, 'r') + except BaseException, X: + EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=F.Path+"\n\t"+str(X)) + + FileContent = Fd.read() + Fd.close() + if len(FileContent) == 0: + continue + + if FileContent[0] == 0xff or FileContent[0] == 0xfe: + FileContent = unicode(FileContent, "utf-16") + IncludedFileList = gIncludePattern.findall(FileContent) + + CurrentFilePath = F.Dir + for Inc in IncludedFileList: + # if there's macro used to reference header file, expand it + HeaderList = gMacroPattern.findall(Inc) + if len(HeaderList) == 1 and len(HeaderList[0]) == 2: + HeaderType = HeaderList[0][0] + HeaderKey = HeaderList[0][1] + if HeaderType in gIncludeMacroConversion: + Inc = gIncludeMacroConversion[HeaderType] % {"HeaderKey" : HeaderKey} + else: + # not known macro used in #include + MacroUsedByIncludedFile = True + continue + Inc = os.path.normpath(Inc) + for SearchPath in [CurrentFilePath] + SearchPathList: + FilePath = os.path.join(SearchPath, Inc) + if not os.path.exists(FilePath) or FilePath in CurrentFileDependencyList: + continue + FilePath = PathClass(FilePath) + CurrentFileDependencyList.append(FilePath) + if FilePath not in FileStack and FilePath not in DependencySet: + FileStack.append(FilePath) + break + else: + EdkLogger.debug(EdkLogger.DEBUG_9, "%s included by %s was not found"\ + "in any given path:\n\t%s" % (Inc, F, "\n\t".join(SearchPathList))) + + if not MacroUsedByIncludedFile: + if F == File: + CurrentFileDependencyList += ForceList + # + # Don't keep the file in cache if it uses macro in included file. + # So it will be scanned again if another file includes this file. + # + DepDb[F] = CurrentFileDependencyList + DependencySet.update(CurrentFileDependencyList) + + # + # If there's macro used in included file, always build the file by + # returning a empty dependency + # + if MacroUsedByIncludedFile: + DependencyList = [] + else: + DependencyList = list(DependencySet) # remove duplicate ones + + return DependencyList + + _TemplateDict = property(_CreateTemplateDict) + +## CustomMakefile class +# +# This class encapsules makefie and its generation for module. It uses template to generate +# the content of makefile. The content of makefile will be got from ModuleAutoGen object. +# +class CustomMakefile(BuildFile): + ## template used to generate the makefile for module with custom makefile + _TEMPLATE_ = TemplateString('''\ +${makefile_header} + +# +# Platform Macro Definition +# +PLATFORM_NAME = ${platform_name} +PLATFORM_GUID = ${platform_guid} +PLATFORM_VERSION = ${platform_version} +PLATFORM_RELATIVE_DIR = ${platform_relative_directory} +PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory} +PLATFORM_OUTPUT_DIR = ${platform_output_directory} + +# +# Module Macro Definition +# +MODULE_NAME = ${module_name} +MODULE_GUID = ${module_guid} +MODULE_VERSION = ${module_version} +MODULE_TYPE = ${module_type} +MODULE_FILE = ${module_file} +MODULE_FILE_BASE_NAME = ${module_file_base_name} +BASE_NAME = $(MODULE_NAME) +MODULE_RELATIVE_DIR = ${module_relative_directory} +MODULE_DIR = $(WORKSPACE)${separator}${module_relative_directory} + +# +# Build Configuration Macro Definition +# +ARCH = ${architecture} +TOOLCHAIN = ${toolchain_tag} +TOOLCHAIN_TAG = ${toolchain_tag} +TARGET = ${build_target} + +# +# Build Directory Macro Definition +# +# PLATFORM_BUILD_DIR = ${platform_build_directory} +BUILD_DIR = ${platform_build_directory} +BIN_DIR = $(BUILD_DIR)${separator}${architecture} +LIB_DIR = $(BIN_DIR) +MODULE_BUILD_DIR = ${module_build_directory} +OUTPUT_DIR = ${module_output_directory} +DEBUG_DIR = ${module_debug_directory} +DEST_DIR_OUTPUT = $(OUTPUT_DIR) +DEST_DIR_DEBUG = $(DEBUG_DIR) + +# +# Tools definitions specific to this module +# +${BEGIN}${module_tool_definitions} +${END} +MAKE_FILE = ${makefile_path} + +# +# Shell Command Macro +# +${BEGIN}${shell_command_code} = ${shell_command} +${END} + +${custom_makefile_content} + +# +# Target used when called from platform makefile, which will bypass the build of dependent libraries +# + +pbuild: init all + + +# +# ModuleTarget +# + +mbuild: init all + +# +# Build Target used in multi-thread build mode, which no init target is needed +# + +tbuild: all + +# +# Initialization target: print build information and create necessary directories +# +init: +\t-@echo Building ... $(MODULE_DIR)${separator}$(MODULE_FILE) [$(ARCH)] +${BEGIN}\t-@${create_directory_command}\n${END}\ + +''') + + ## Constructor of CustomMakefile + # + # @param ModuleAutoGen Object of ModuleAutoGen class + # + def __init__(self, ModuleAutoGen): + BuildFile.__init__(self, ModuleAutoGen) + self.PlatformInfo = self._AutoGenObject.PlatformInfo + self.IntermediateDirectoryList = ["$(DEBUG_DIR)", "$(OUTPUT_DIR)"] + + # Compose a dict object containing information used to do replacement in template + def _CreateTemplateDict(self): + Separator = self._SEP_[self._FileType] + if self._FileType not in self._AutoGenObject.CustomMakefile: + EdkLogger.error('build', OPTION_NOT_SUPPORTED, "No custom makefile for %s" % self._FileType, + ExtraData="[%s]" % str(self._AutoGenObject)) + MakefilePath = os.path.join( + self._AutoGenObject.WorkspaceDir, + self._AutoGenObject.CustomMakefile[self._FileType] + ) + try: + CustomMakefile = open(MakefilePath, 'r').read() + except: + EdkLogger.error('build', FILE_OPEN_FAILURE, File=str(self._AutoGenObject), + ExtraData=self._AutoGenObject.CustomMakefile[self._FileType]) + + # tools definitions + ToolsDef = [] + for Tool in self._AutoGenObject.BuildOption: + # Don't generate MAKE_FLAGS in makefile. It's put in environment variable. + if Tool == "MAKE": + continue + for Attr in self._AutoGenObject.BuildOption[Tool]: + if Attr == "FAMILY": + continue + elif Attr == "PATH": + ToolsDef.append("%s = %s" % (Tool, self._AutoGenObject.BuildOption[Tool][Attr])) + else: + ToolsDef.append("%s_%s = %s" % (Tool, Attr, self._AutoGenObject.BuildOption[Tool][Attr])) + ToolsDef.append("") + + MakefileName = self._FILE_NAME_[self._FileType] + MakefileTemplateDict = { + "makefile_header" : self._FILE_HEADER_[self._FileType], + "makefile_path" : os.path.join("$(MODULE_BUILD_DIR)", MakefileName), + "platform_name" : self.PlatformInfo.Name, + "platform_guid" : self.PlatformInfo.Guid, + "platform_version" : self.PlatformInfo.Version, + "platform_relative_directory": self.PlatformInfo.SourceDir, + "platform_output_directory" : self.PlatformInfo.OutputDir, + + "module_name" : self._AutoGenObject.Name, + "module_guid" : self._AutoGenObject.Guid, + "module_version" : self._AutoGenObject.Version, + "module_type" : self._AutoGenObject.ModuleType, + "module_file" : self._AutoGenObject.MetaFile, + "module_file_base_name" : self._AutoGenObject.MetaFile.BaseName, + "module_relative_directory" : self._AutoGenObject.SourceDir, + + "architecture" : self._AutoGenObject.Arch, + "toolchain_tag" : self._AutoGenObject.ToolChain, + "build_target" : self._AutoGenObject.BuildTarget, + + "platform_build_directory" : self.PlatformInfo.BuildDir, + "module_build_directory" : self._AutoGenObject.BuildDir, + "module_output_directory" : self._AutoGenObject.OutputDir, + "module_debug_directory" : self._AutoGenObject.DebugDir, + + "separator" : Separator, + "module_tool_definitions" : ToolsDef, + + "shell_command_code" : self._SHELL_CMD_[self._FileType].keys(), + "shell_command" : self._SHELL_CMD_[self._FileType].values(), + + "create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList), + "custom_makefile_content" : CustomMakefile + } + + return MakefileTemplateDict + + _TemplateDict = property(_CreateTemplateDict) + +## PlatformMakefile class +# +# This class encapsules makefie and its generation for platform. It uses +# template to generate the content of makefile. The content of makefile will be +# got from PlatformAutoGen object. +# +class PlatformMakefile(BuildFile): + ## template used to generate the makefile for platform + _TEMPLATE_ = TemplateString('''\ +${makefile_header} + +# +# Platform Macro Definition +# +PLATFORM_NAME = ${platform_name} +PLATFORM_GUID = ${platform_guid} +PLATFORM_VERSION = ${platform_version} +PLATFORM_FILE = ${platform_file} +PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory} +PLATFORM_OUTPUT_DIR = ${platform_output_directory} + +# +# Build Configuration Macro Definition +# +TOOLCHAIN = ${toolchain_tag} +TOOLCHAIN_TAG = ${toolchain_tag} +TARGET = ${build_target} + +# +# Build Directory Macro Definition +# +BUILD_DIR = ${platform_build_directory} +FV_DIR = ${platform_build_directory}${separator}FV + +# +# Shell Command Macro +# +${BEGIN}${shell_command_code} = ${shell_command} +${END} + +MAKE = ${make_path} +MAKE_FILE = ${makefile_path} + +# +# Default target +# +all: init build_libraries build_modules + +# +# Initialization target: print build information and create necessary directories +# +init: +\t-@echo Building ... $(PLATFORM_FILE) [${build_architecture_list}] +\t${BEGIN}-@${create_directory_command} +\t${END} +# +# library build target +# +libraries: init build_libraries + +# +# module build target +# +modules: init build_libraries build_modules + +# +# Build all libraries: +# +build_libraries: +${BEGIN}\t@"$(MAKE)" $(MAKE_FLAGS) -f ${library_makefile_list} pbuild +${END}\t@cd $(BUILD_DIR) + +# +# Build all modules: +# +build_modules: +${BEGIN}\t@"$(MAKE)" $(MAKE_FLAGS) -f ${module_makefile_list} pbuild +${END}\t@cd $(BUILD_DIR) + +# +# Clean intermediate files +# +clean: +\t${BEGIN}-@${library_build_command} clean +\t${END}${BEGIN}-@${module_build_command} clean +\t${END}@cd $(BUILD_DIR) + +# +# Clean all generated files except to makefile +# +cleanall: +${BEGIN}\t${cleanall_command} +${END} + +# +# Clean all library files +# +cleanlib: +\t${BEGIN}-@${library_build_command} cleanall +\t${END}@cd $(BUILD_DIR)\n +''') + + ## Constructor of PlatformMakefile + # + # @param ModuleAutoGen Object of PlatformAutoGen class + # + def __init__(self, PlatformAutoGen): + BuildFile.__init__(self, PlatformAutoGen) + self.ModuleBuildCommandList = [] + self.ModuleMakefileList = [] + self.IntermediateDirectoryList = [] + self.ModuleBuildDirectoryList = [] + self.LibraryBuildDirectoryList = [] + + # Compose a dict object containing information used to do replacement in template + def _CreateTemplateDict(self): + Separator = self._SEP_[self._FileType] + + PlatformInfo = self._AutoGenObject + if "MAKE" not in PlatformInfo.ToolDefinition or "PATH" not in PlatformInfo.ToolDefinition["MAKE"]: + EdkLogger.error("build", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!", + ExtraData="[%s]" % str(self._AutoGenObject)) + + self.IntermediateDirectoryList = ["$(BUILD_DIR)"] + self.ModuleBuildDirectoryList = self.GetModuleBuildDirectoryList() + self.LibraryBuildDirectoryList = self.GetLibraryBuildDirectoryList() + + MakefileName = self._FILE_NAME_[self._FileType] + LibraryMakefileList = [] + LibraryMakeCommandList = [] + for D in self.LibraryBuildDirectoryList: + D = self.PlaceMacro(D, {"BUILD_DIR":PlatformInfo.BuildDir}) + Makefile = os.path.join(D, MakefileName) + Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":Makefile} + LibraryMakefileList.append(Makefile) + LibraryMakeCommandList.append(Command) + + ModuleMakefileList = [] + ModuleMakeCommandList = [] + for D in self.ModuleBuildDirectoryList: + D = self.PlaceMacro(D, {"BUILD_DIR":PlatformInfo.BuildDir}) + Makefile = os.path.join(D, MakefileName) + Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":Makefile} + ModuleMakefileList.append(Makefile) + ModuleMakeCommandList.append(Command) + + MakefileTemplateDict = { + "makefile_header" : self._FILE_HEADER_[self._FileType], + "makefile_path" : os.path.join("$(BUILD_DIR)", MakefileName), + "make_path" : PlatformInfo.ToolDefinition["MAKE"]["PATH"], + "makefile_name" : MakefileName, + "platform_name" : PlatformInfo.Name, + "platform_guid" : PlatformInfo.Guid, + "platform_version" : PlatformInfo.Version, + "platform_file" : self._AutoGenObject.MetaFile, + "platform_relative_directory": PlatformInfo.SourceDir, + "platform_output_directory" : PlatformInfo.OutputDir, + "platform_build_directory" : PlatformInfo.BuildDir, + + "toolchain_tag" : PlatformInfo.ToolChain, + "build_target" : PlatformInfo.BuildTarget, + "shell_command_code" : self._SHELL_CMD_[self._FileType].keys(), + "shell_command" : self._SHELL_CMD_[self._FileType].values(), + "build_architecture_list" : self._AutoGenObject.Arch, + "architecture" : self._AutoGenObject.Arch, + "separator" : Separator, + "create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList), + "cleanall_command" : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList), + "library_makefile_list" : LibraryMakefileList, + "module_makefile_list" : ModuleMakefileList, + "library_build_command" : LibraryMakeCommandList, + "module_build_command" : ModuleMakeCommandList, + } + + return MakefileTemplateDict + + ## Get the root directory list for intermediate files of all modules build + # + # @retval list The list of directory + # + def GetModuleBuildDirectoryList(self): + DirList = [] + for ModuleAutoGen in self._AutoGenObject.ModuleAutoGenList: + DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir)) + return DirList + + ## Get the root directory list for intermediate files of all libraries build + # + # @retval list The list of directory + # + def GetLibraryBuildDirectoryList(self): + DirList = [] + for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList: + DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir)) + return DirList + + _TemplateDict = property(_CreateTemplateDict) + +## TopLevelMakefile class +# +# This class encapsules makefie and its generation for entrance makefile. It +# uses template to generate the content of makefile. The content of makefile +# will be got from WorkspaceAutoGen object. +# +class TopLevelMakefile(BuildFile): + ## template used to generate toplevel makefile + _TEMPLATE_ = TemplateString('''\ +${makefile_header} + +# +# Platform Macro Definition +# +PLATFORM_NAME = ${platform_name} +PLATFORM_GUID = ${platform_guid} +PLATFORM_VERSION = ${platform_version} + +# +# Build Configuration Macro Definition +# +TOOLCHAIN = ${toolchain_tag} +TOOLCHAIN_TAG = ${toolchain_tag} +TARGET = ${build_target} + +# +# Build Directory Macro Definition +# +BUILD_DIR = ${platform_build_directory} +FV_DIR = ${platform_build_directory}${separator}FV + +# +# Shell Command Macro +# +${BEGIN}${shell_command_code} = ${shell_command} +${END} + +MAKE = ${make_path} +MAKE_FILE = ${makefile_path} + +# +# Default target +# +all: modules fds + +# +# Initialization target: print build information and create necessary directories +# +init: +\t-@ +\t${BEGIN}-@${create_directory_command} +\t${END} +# +# library build target +# +libraries: init +${BEGIN}\t@cd $(BUILD_DIR)${separator}${arch} && "$(MAKE)" $(MAKE_FLAGS) libraries +${END}\t@cd $(BUILD_DIR) + +# +# module build target +# +modules: init +${BEGIN}\t@cd $(BUILD_DIR)${separator}${arch} && "$(MAKE)" $(MAKE_FLAGS) modules +${END}\t@cd $(BUILD_DIR) + +# +# Flash Device Image Target +# +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} + +# +# run command for emulator platform only +# +run: +\tcd $(BUILD_DIR)${separator}IA32 && ".${separator}SecMain" +\tcd $(BUILD_DIR) + +# +# Clean intermediate files +# +clean: +${BEGIN}\t-@${sub_build_command} clean +${END}\t@cd $(BUILD_DIR) + +# +# Clean all generated files except to makefile +# +cleanall: +${BEGIN}\t${cleanall_command} +${END} + +# +# Clean all library files +# +cleanlib: +${BEGIN}\t-@${sub_build_command} cleanlib +${END}\t@cd $(BUILD_DIR)\n +''') + + ## Constructor of TopLevelMakefile + # + # @param Workspace Object of WorkspaceAutoGen class + # + def __init__(self, Workspace): + BuildFile.__init__(self, Workspace) + self.IntermediateDirectoryList = [] + + # Compose a dict object containing information used to do replacement in template + def _CreateTemplateDict(self): + Separator = self._SEP_[self._FileType] + + # any platform autogen object is ok because we just need common information + PlatformInfo = self._AutoGenObject + + if "MAKE" not in PlatformInfo.ToolDefinition or "PATH" not in PlatformInfo.ToolDefinition["MAKE"]: + EdkLogger.error("build", OPTION_MISSING, "No MAKE command defined. Please check your tools_def.txt!", + ExtraData="[%s]" % str(self._AutoGenObject)) + + for Arch in PlatformInfo.ArchList: + self.IntermediateDirectoryList.append(Separator.join(["$(BUILD_DIR)", Arch])) + self.IntermediateDirectoryList.append("$(FV_DIR)") + + # TRICK: for not generating GenFds call in makefile if no FDF file + MacroList = [] + if PlatformInfo.FdfFile != None and PlatformInfo.FdfFile != "": + FdfFileList = [PlatformInfo.FdfFile] + # macros passed to GenFds + for MacroName in GlobalData.gGlobalDefines: + MacroList.append('"%s=%s"' % (MacroName, GlobalData.gGlobalDefines[MacroName])) + else: + FdfFileList = [] + + # pass extra common options to external program called in makefile, currently GenFds.exe + ExtraOption = '' + LogLevel = EdkLogger.GetLevel() + if LogLevel == EdkLogger.VERBOSE: + ExtraOption += " -v" + elif LogLevel <= EdkLogger.DEBUG_9: + ExtraOption += " -d %d" % (LogLevel - 1) + elif LogLevel == EdkLogger.QUIET: + ExtraOption += " -q" + + if GlobalData.gCaseInsensitive: + ExtraOption += " -c" + + MakefileName = self._FILE_NAME_[self._FileType] + SubBuildCommandList = [] + for A in PlatformInfo.ArchList: + Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join("$(BUILD_DIR)", A, MakefileName)} + SubBuildCommandList.append(Command) + + MakefileTemplateDict = { + "makefile_header" : self._FILE_HEADER_[self._FileType], + "makefile_path" : os.path.join("$(BUILD_DIR)", MakefileName), + "make_path" : PlatformInfo.ToolDefinition["MAKE"]["PATH"], + "platform_name" : PlatformInfo.Name, + "platform_guid" : PlatformInfo.Guid, + "platform_version" : PlatformInfo.Version, + "platform_build_directory" : PlatformInfo.BuildDir, + + "toolchain_tag" : PlatformInfo.ToolChain, + "build_target" : PlatformInfo.BuildTarget, + "shell_command_code" : self._SHELL_CMD_[self._FileType].keys(), + "shell_command" : self._SHELL_CMD_[self._FileType].values(), + 'arch' : list(PlatformInfo.ArchList), + "build_architecture_list" : ','.join(PlatformInfo.ArchList), + "separator" : Separator, + "create_directory_command" : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList), + "cleanall_command" : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList), + "sub_build_command" : SubBuildCommandList, + "fdf_file" : FdfFileList, + "active_platform" : str(PlatformInfo), + "fd" : PlatformInfo.FdTargetList, + "fv" : PlatformInfo.FvTargetList, + "extra_options" : ExtraOption, + "macro" : MacroList, + } + + return MakefileTemplateDict + + ## Get the root directory list for intermediate files of all modules build + # + # @retval list The list of directory + # + def GetModuleBuildDirectoryList(self): + DirList = [] + for ModuleAutoGen in self._AutoGenObject.ModuleAutoGenList: + DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir)) + return DirList + + ## Get the root directory list for intermediate files of all libraries build + # + # @retval list The list of directory + # + def GetLibraryBuildDirectoryList(self): + DirList = [] + for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList: + DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir)) + return DirList + + _TemplateDict = property(_CreateTemplateDict) + +# This acts like the main() function for the script, unless it is 'import'ed into another script. +if __name__ == '__main__': + pass + diff --git a/BaseTools/Source/Python/AutoGen/StrGather.py b/BaseTools/Source/Python/AutoGen/StrGather.py new file mode 100644 index 0000000000..e82ad3a10b --- /dev/null +++ b/BaseTools/Source/Python/AutoGen/StrGather.py @@ -0,0 +1,532 @@ +# Copyright (c) 2007, 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 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 is used to parse a strings file and create or add to a string database file. +# + +## +# Import Modules +# +import re +import Common.EdkLogger as EdkLogger +from Common.BuildToolError import * +from UniClassObject import * + +## +# Static definitions +# +EFI_HII_SIBT_END = '0x00' +EFI_HII_SIBT_STRING_SCSU = '0x10' +EFI_HII_SIBT_STRING_SCSU_FONT = '0x11' +EFI_HII_SIBT_STRINGS_SCSU = '0x12' +EFI_HII_SIBT_STRINGS_SCSU_FONT = '0x13' +EFI_HII_SIBT_STRING_UCS2 = '0x14' +EFI_HII_SIBT_STRING_UCS2_FONT = '0x15' +EFI_HII_SIBT_STRINGS_UCS2 = '0x16' +EFI_HII_SIBT_STRINGS_UCS2_FONT = '0x17' +EFI_HII_SIBT_DUPLICATE = '0x20' +EFI_HII_SIBT_SKIP2 = '0x21' +EFI_HII_SIBT_SKIP1 = '0x22' +EFI_HII_SIBT_EXT1 = '0x30' +EFI_HII_SIBT_EXT2 = '0x31' +EFI_HII_SIBT_EXT4 = '0x32' +EFI_HII_SIBT_FONT = '0x40' + +EFI_HII_PACKAGE_STRINGS = '0x04' +EFI_HII_PACKAGE_FORM = '0x02' + +StringPackageType = EFI_HII_PACKAGE_STRINGS +StringPackageForm = EFI_HII_PACKAGE_FORM +StringBlockType = EFI_HII_SIBT_STRING_UCS2 +StringSkipType = EFI_HII_SIBT_SKIP2 + +HexHeader = '0x' + +COMMENT = '// ' +DEFINE_STR = '#define' +COMMENT_DEFINE_STR = COMMENT + DEFINE_STR +NOT_REFERENCED = 'not referenced' +COMMENT_NOT_REFERENCED = ' ' + COMMENT + NOT_REFERENCED +CHAR_ARRAY_DEFIN = 'unsigned char' +COMMON_FILE_NAME = 'Strings' +OFFSET = 'offset' +STRING = 'string' +TO = 'to' +STRING_TOKEN = re.compile('STRING_TOKEN *\(([A-Z0-9_]+) *\)', re.MULTILINE | re.UNICODE) + +EFI_HII_ARRAY_SIZE_LENGTH = 4 +EFI_HII_PACKAGE_HEADER_LENGTH = 4 +EFI_HII_HDR_SIZE_LENGTH = 4 +EFI_HII_STRING_OFFSET_LENGTH = 4 +EFI_STRING_ID = 1 +EFI_STRING_ID_LENGTH = 2 +EFI_HII_LANGUAGE_WINDOW = 0 +EFI_HII_LANGUAGE_WINDOW_LENGTH = 2 +EFI_HII_LANGUAGE_WINDOW_NUMBER = 16 +EFI_HII_STRING_PACKAGE_HDR_LENGTH = EFI_HII_PACKAGE_HEADER_LENGTH + EFI_HII_HDR_SIZE_LENGTH + EFI_HII_STRING_OFFSET_LENGTH + EFI_HII_LANGUAGE_WINDOW_LENGTH * EFI_HII_LANGUAGE_WINDOW_NUMBER + EFI_STRING_ID_LENGTH + +H_C_FILE_HEADER = ['//', \ + '// DO NOT EDIT -- auto-generated file', \ + '//', \ + '// This file is generated by the StrGather utility', \ + '//'] +LANGUAGE_NAME_STRING_NAME = '$LANGUAGE_NAME' +PRINTABLE_LANGUAGE_NAME_STRING_NAME = '$PRINTABLE_LANGUAGE_NAME' + +## Convert a dec number to a hex string +# +# Convert a dec number to a formatted hex string in length digit +# The digit is set to default 8 +# The hex string starts with "0x" +# DecToHexStr(1000) is '0x000003E8' +# DecToHexStr(1000, 6) is '0x0003E8' +# +# @param Dec: The number in dec format +# @param Digit: The needed digit of hex string +# +# @retval: The formatted hex string +# +def DecToHexStr(Dec, Digit = 8): + return eval("'0x%0" + str(Digit) + "X' % int(Dec)") + +## Convert a dec number to a hex list +# +# Convert a dec number to a formatted hex list in size digit +# The digit is set to default 8 +# DecToHexList(1000) is ['0xE8', '0x03', '0x00', '0x00'] +# DecToHexList(1000, 6) is ['0xE8', '0x03', '0x00'] +# +# @param Dec: The number in dec format +# @param Digit: The needed digit of hex list +# +# @retval: A list for formatted hex string +# +def DecToHexList(Dec, Digit = 8): + Hex = eval("'%0" + str(Digit) + "X' % int(Dec)" ) + List = [] + for Bit in range(Digit - 2, -1, -2): + List.append(HexHeader + Hex[Bit:Bit + 2]) + return List + +## Convert a acsii string to a hex list +# +# Convert a acsii string to a formatted hex list +# AscToHexList('en-US') is ['0x65', '0x6E', '0x2D', '0x55', '0x53'] +# +# @param Ascii: The acsii string +# +# @retval: A list for formatted hex string +# +def AscToHexList(Ascii): + List = [] + for Item in Ascii: + List.append('0x%2X' % ord(Item)) + + return List + +## Create header of .h file +# +# Create a header of .h file +# +# @param BaseName: The basename of strings +# +# @retval Str: A string for .h file header +# +def CreateHFileHeader(BaseName): + Str = '' + for Item in H_C_FILE_HEADER: + Str = WriteLine(Str, Item) + Str = WriteLine(Str, '#ifndef _' + BaseName.upper() + '_STRINGS_DEFINE_H_') + Str = WriteLine(Str, '#define _' + BaseName.upper() + '_STRINGS_DEFINE_H_') + return Str + +## Create content of .h file +# +# Create content of .h file +# +# @param BaseName: The basename of strings +# @param UniObjectClass: A UniObjectClass instance +# +# @retval Str: A string of .h file content +# +def CreateHFileContent(BaseName, UniObjectClass): + Str = '' + ValueStartPtr = 60 + Line = COMMENT_DEFINE_STR + ' ' + LANGUAGE_NAME_STRING_NAME + ' ' * (ValueStartPtr - len(DEFINE_STR + LANGUAGE_NAME_STRING_NAME)) + DecToHexStr(0, 4) + COMMENT_NOT_REFERENCED + Str = WriteLine(Str, Line) + Line = COMMENT_DEFINE_STR + ' ' + PRINTABLE_LANGUAGE_NAME_STRING_NAME + ' ' * (ValueStartPtr - len(DEFINE_STR + PRINTABLE_LANGUAGE_NAME_STRING_NAME)) + DecToHexStr(1, 4) + COMMENT_NOT_REFERENCED + Str = WriteLine(Str, Line) + for Index in range(2, len(UniObjectClass.OrderedStringList[UniObjectClass.LanguageDef[0][0]])): + StringItem = UniObjectClass.OrderedStringList[UniObjectClass.LanguageDef[0][0]][Index] + Name = StringItem.StringName + Token = StringItem.Token + Referenced = StringItem.Referenced + if Name != None: + Line = '' + if Referenced == True: + Line = DEFINE_STR + ' ' + Name + ' ' * (ValueStartPtr - len(DEFINE_STR + Name)) + DecToHexStr(Token, 4) + else: + Line = COMMENT_DEFINE_STR + ' ' + Name + ' ' * (ValueStartPtr - len(DEFINE_STR + Name)) + DecToHexStr(Token, 4) + COMMENT_NOT_REFERENCED + Str = WriteLine(Str, Line) + + Str = WriteLine(Str, '') + Str = WriteLine(Str, 'extern unsigned char ' + BaseName + 'Strings[];') + return Str + +## Create a complete .h file +# +# Create a complet .h file with file header and file content +# +# @param BaseName: The basename of strings +# @param UniObjectClass: A UniObjectClass instance +# +# @retval Str: A string of complete .h file +# +def CreateHFile(BaseName, UniObjectClass): + HFile = WriteLine('', CreateHFileContent(BaseName, UniObjectClass)) + + return HFile + +## Create header of .c file +# +# Create a header of .c file +# +# @retval Str: A string for .c file header +# +def CreateCFileHeader(): + Str = '' + for Item in H_C_FILE_HEADER: + Str = WriteLine(Str, Item) + + return Str + +## Create a formatted string all items in an array +# +# Use ',' to join each item in an array, and break an new line when reaching the width (default is 16) +# +# @param Array: The array need to be formatted +# @param Width: The line length, the default value is set to 16 +# +# @retval ArrayItem: A string for all formatted array items +# +def CreateArrayItem(Array, Width = 16): + MaxLength = Width + Index = 0 + Line = ' ' + ArrayItem = '' + + for Item in Array: + if Index < MaxLength: + Line = Line + Item + ', ' + Index = Index + 1 + else: + ArrayItem = WriteLine(ArrayItem, Line) + Line = ' ' + Item + ', ' + Index = 1 + ArrayItem = Write(ArrayItem, Line.rstrip()) + + return ArrayItem + +## CreateCFileStringValue +# +# Create a line with string value +# +# @param Value: Value of the string +# +# @retval Str: A formatted string with string value +# + +def CreateCFileStringValue(Value): + Value = [StringBlockType] + Value + Str = WriteLine('', CreateArrayItem(Value)) + + return Str + + +## Create content of .c file +# +# Create content of .c file +# +# @param BaseName: The basename of strings +# @param UniObjectClass: A UniObjectClass instance +# +# @retval Str: A string of .c file content +# +def CreateCFileContent(BaseName, UniObjectClass, IsCompatibleMode): + # + # Init array length + # + TotalLength = EFI_HII_ARRAY_SIZE_LENGTH + Str = '' + Offset = 0 + + # + # Create lines for each language's strings + # + for IndexI in range(len(UniObjectClass.LanguageDef)): + Language = UniObjectClass.LanguageDef[IndexI][0] + LangPrintName = UniObjectClass.LanguageDef[IndexI][1] + + StrStringValue = '' + ArrayLength = 0 + NumberOfUseOhterLangDef = 0 + Index = 0 + for IndexJ in range(1, len(UniObjectClass.OrderedStringList[UniObjectClass.LanguageDef[IndexI][0]])): + Item = UniObjectClass.FindByToken(IndexJ, Language) + Name = Item.StringName + Value = Item.StringValueByteList + Referenced = Item.Referenced + Token = Item.Token + Length = Item.Length + UseOtherLangDef = Item.UseOtherLangDef + + if UseOtherLangDef != '' and Referenced: + NumberOfUseOhterLangDef = NumberOfUseOhterLangDef + 1 + Index = Index + 1 + else: + if NumberOfUseOhterLangDef > 0: + StrStringValue = WriteLine(StrStringValue, CreateArrayItem([StringSkipType] + DecToHexList(NumberOfUseOhterLangDef, 4))) + NumberOfUseOhterLangDef = 0 + ArrayLength = ArrayLength + 3 + if Referenced and Item.Token > 0: + Index = Index + 1 + StrStringValue = WriteLine(StrStringValue, "// %s: %s:%s" % (DecToHexStr(Index, 4), Name, DecToHexStr(Token, 4))) + StrStringValue = Write(StrStringValue, CreateCFileStringValue(Value)) + Offset = Offset + Length + ArrayLength = ArrayLength + Item.Length + 1 # 1 is for the length of string type + + # + # EFI_HII_PACKAGE_HEADER + # + Offset = EFI_HII_STRING_PACKAGE_HDR_LENGTH + len(Language) + 1 + ArrayLength = Offset + ArrayLength + 1 + + # + # Create PACKAGE HEADER + # + Str = WriteLine(Str, '// PACKAGE HEADER\n') + TotalLength = TotalLength + ArrayLength + + List = DecToHexList(ArrayLength, 6) + \ + [StringPackageType] + \ + DecToHexList(Offset) + \ + DecToHexList(Offset) + \ + DecToHexList(EFI_HII_LANGUAGE_WINDOW, EFI_HII_LANGUAGE_WINDOW_LENGTH * 2) * EFI_HII_LANGUAGE_WINDOW_NUMBER + \ + DecToHexList(EFI_STRING_ID, 4) + \ + AscToHexList(Language) + \ + DecToHexList(0, 2) + Str = WriteLine(Str, CreateArrayItem(List, 16) + '\n') + + # + # Create PACKAGE DATA + # + Str = WriteLine(Str, '// PACKAGE DATA\n') + Str = Write(Str, StrStringValue) + + # + # Add an EFI_HII_SIBT_END at last + # + Str = WriteLine(Str, ' ' + EFI_HII_SIBT_END + ",") + + # + # Create line for string variable name + # "unsigned char $(BaseName)Strings[] = {" + # + AllStr = WriteLine('', CHAR_ARRAY_DEFIN + ' ' + BaseName + COMMON_FILE_NAME + '[] = {\n' ) + + # + # Create FRAMEWORK_EFI_HII_PACK_HEADER in compatible mode + # + if IsCompatibleMode: + AllStr = WriteLine(AllStr, '// FRAMEWORK PACKAGE HEADER Length') + AllStr = WriteLine(AllStr, CreateArrayItem(DecToHexList(TotalLength + 2)) + '\n') + AllStr = WriteLine(AllStr, '// FRAMEWORK PACKAGE HEADER Type') + AllStr = WriteLine(AllStr, CreateArrayItem(DecToHexList(2, 4)) + '\n') + + # + # Create whole array length in UEFI mode + # + if not IsCompatibleMode: + AllStr = WriteLine(AllStr, '// STRGATHER_OUTPUT_HEADER') + AllStr = WriteLine(AllStr, CreateArrayItem(DecToHexList(TotalLength)) + '\n') + + # + # Join package data + # + AllStr = Write(AllStr, Str) + + return AllStr + +## Create end of .c file +# +# Create end of .c file +# +# @retval Str: A string of .h file end +# +def CreateCFileEnd(): + Str = Write('', '};') + return Str + +## Create a .c file +# +# Create a complete .c file +# +# @param BaseName: The basename of strings +# @param UniObjectClass: A UniObjectClass instance +# +# @retval CFile: A string of complete .c file +# +def CreateCFile(BaseName, UniObjectClass, IsCompatibleMode): + CFile = '' + #CFile = WriteLine(CFile, CreateCFileHeader()) + CFile = WriteLine(CFile, CreateCFileContent(BaseName, UniObjectClass, IsCompatibleMode)) + CFile = WriteLine(CFile, CreateCFileEnd()) + return CFile + +## GetFileList +# +# Get a list for all files +# +# @param IncludeList: A list of all path to be searched +# @param SkipList: A list of all types of file could be skipped +# +# @retval FileList: A list of all files found +# +def GetFileList(SourceFileList, IncludeList, SkipList): + if IncludeList == None: + EdkLogger.error("UnicodeStringGather", AUTOGEN_ERROR, "Include path for unicode file is not defined") + + FileList = [] + if SkipList == None: + SkipList = [] + + for File in SourceFileList: + for Dir in IncludeList: + if not os.path.exists(Dir): + continue + File = os.path.join(Dir, File.Path) + # + # Ignore Dir + # + if os.path.isfile(File) != True: + continue + # + # Ignore file listed in skip list + # + IsSkip = False + for Skip in SkipList: + if os.path.splitext(File)[1].upper() == Skip.upper(): + EdkLogger.verbose("Skipped %s for string token uses search" % File) + IsSkip = True + break + + if not IsSkip: + FileList.append(File) + + break + + return FileList + +## SearchString +# +# Search whether all string defined in UniObjectClass are referenced +# All string used should be set to Referenced +# +# @param UniObjectClass: Input UniObjectClass +# @param FileList: Search path list +# +# @retval UniObjectClass: UniObjectClass after searched +# +def SearchString(UniObjectClass, FileList): + if FileList == []: + return UniObjectClass + + for File in FileList: + if os.path.isfile(File): + Lines = open(File, 'r') + for Line in Lines: + StringTokenList = STRING_TOKEN.findall(Line) + for StrName in StringTokenList: + EdkLogger.debug(EdkLogger.DEBUG_5, "Found string identifier: " + StrName) + UniObjectClass.SetStringReferenced(StrName) + + UniObjectClass.ReToken() + + return UniObjectClass + +## GetStringFiles +# +# This function is used for UEFI2.1 spec +# +# +def GetStringFiles(UniFilList, SourceFileList, IncludeList, SkipList, BaseName, IsCompatibleMode = False, ShellMode = False): + Status = True + ErrorMessage = '' + + if len(UniFilList) > 0: + if ShellMode: + # + # support ISO 639-2 codes in .UNI files of EDK Shell + # + Uni = UniFileClassObject(UniFilList, True) + else: + Uni = UniFileClassObject(UniFilList, IsCompatibleMode) + else: + EdkLogger.error("UnicodeStringGather", AUTOGEN_ERROR, 'No unicode files given') + + FileList = GetFileList(SourceFileList, IncludeList, SkipList) + + Uni = SearchString(Uni, FileList) + + HFile = CreateHFile(BaseName, Uni) + CFile = CreateCFile(BaseName, Uni, IsCompatibleMode) + + return HFile, CFile + +# +# Write an item +# +def Write(Target, Item): + return Target + Item + +# +# Write an item with a break line +# +def WriteLine(Target, Item): + return Target + Item + '\n' + +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +if __name__ == '__main__': + EdkLogger.info('start') + + UniFileList = [ + r'C:\\Edk\\Strings2.uni', + r'C:\\Edk\\Strings.uni' + ] + + SrcFileList = [] + for Root, Dirs, Files in os.walk('C:\\Edk'): + for File in Files: + SrcFileList.append(File) + + IncludeList = [ + r'C:\\Edk' + ] + + SkipList = ['.inf', '.uni'] + BaseName = 'DriverSample' + (h, c) = GetStringFiles(UniFileList, SrcFileList, IncludeList, SkipList, BaseName, True) + hfile = open('unistring.h', 'w') + cfile = open('unistring.c', 'w') + hfile.write(h) + cfile.write(c) + + EdkLogger.info('end') diff --git a/BaseTools/Source/Python/AutoGen/UniClassObject.py b/BaseTools/Source/Python/AutoGen/UniClassObject.py new file mode 100644 index 0000000000..412fa72df0 --- /dev/null +++ b/BaseTools/Source/Python/AutoGen/UniClassObject.py @@ -0,0 +1,530 @@ +# Copyright (c) 2007, 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 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 is used to collect all defined strings in multiple uni files +# + +## +# Import Modules +# +import os, codecs, re +import Common.EdkLogger as EdkLogger +from Common.BuildToolError import * +from Common.String import GetLineNo +from Common.Misc import PathClass + +## +# Static definitions +# +UNICODE_WIDE_CHAR = u'\\wide' +UNICODE_NARROW_CHAR = u'\\narrow' +UNICODE_NON_BREAKING_CHAR = u'\\nbr' +UNICODE_UNICODE_CR = '\r' +UNICODE_UNICODE_LF = '\n' + +NARROW_CHAR = u'\uFFF0' +WIDE_CHAR = u'\uFFF1' +NON_BREAKING_CHAR = u'\uFFF2' +CR = u'\u000D' +LF = u'\u000A' +NULL = u'\u0000' +TAB = u'\t' +BACK_SPLASH = u'\\' + +gIncludePattern = re.compile("^#include +[\"<]+([^\"< >]+)[>\"]+$", re.MULTILINE | re.UNICODE) + +## Convert a python unicode string to a normal string +# +# Convert a python unicode string to a normal string +# UniToStr(u'I am a string') is 'I am a string' +# +# @param Uni: The python unicode string +# +# @retval: The formatted normal string +# +def UniToStr(Uni): + return repr(Uni)[2:-1] + +## Convert a unicode string to a Hex list +# +# Convert a unicode string to a Hex list +# UniToHexList('ABC') is ['0x41', '0x00', '0x42', '0x00', '0x43', '0x00'] +# +# @param Uni: The python unicode string +# +# @retval List: The formatted hex list +# +def UniToHexList(Uni): + List = [] + for Item in Uni: + Temp = '%04X' % ord(Item) + List.append('0x' + Temp[2:4]) + List.append('0x' + Temp[0:2]) + return List + +LangConvTable = {'eng':'en', 'fra':'fr', \ + 'aar':'aa', 'abk':'ab', 'ave':'ae', 'afr':'af', 'aka':'ak', 'amh':'am', \ + 'arg':'an', 'ara':'ar', 'asm':'as', 'ava':'av', 'aym':'ay', 'aze':'az', \ + 'bak':'ba', 'bel':'be', 'bul':'bg', 'bih':'bh', 'bis':'bi', 'bam':'bm', \ + 'ben':'bn', 'bod':'bo', 'bre':'br', 'bos':'bs', 'cat':'ca', 'che':'ce', \ + 'cha':'ch', 'cos':'co', 'cre':'cr', 'ces':'cs', 'chu':'cu', 'chv':'cv', \ + 'cym':'cy', 'dan':'da', 'deu':'de', 'div':'dv', 'dzo':'dz', 'ewe':'ee', \ + 'ell':'el', 'epo':'eo', 'spa':'es', 'est':'et', 'eus':'eu', 'fas':'fa', \ + 'ful':'ff', 'fin':'fi', 'fij':'fj', 'fao':'fo', 'fry':'fy', 'gle':'ga', \ + 'gla':'gd', 'glg':'gl', 'grn':'gn', 'guj':'gu', 'glv':'gv', 'hau':'ha', \ + 'heb':'he', 'hin':'hi', 'hmo':'ho', 'hrv':'hr', 'hat':'ht', 'hun':'hu', \ + 'hye':'hy', 'her':'hz', 'ina':'ia', 'ind':'id', 'ile':'ie', 'ibo':'ig', \ + 'iii':'ii', 'ipk':'ik', 'ido':'io', 'isl':'is', 'ita':'it', 'iku':'iu', \ + 'jpn':'ja', 'jav':'jv', 'kat':'ka', 'kon':'kg', 'kik':'ki', 'kua':'kj', \ + 'kaz':'kk', 'kal':'kl', 'khm':'km', 'kan':'kn', 'kor':'ko', 'kau':'kr', \ + 'kas':'ks', 'kur':'ku', 'kom':'kv', 'cor':'kw', 'kir':'ky', 'lat':'la', \ + 'ltz':'lb', 'lug':'lg', 'lim':'li', 'lin':'ln', 'lao':'lo', 'lit':'lt', \ + 'lub':'lu', 'lav':'lv', 'mlg':'mg', 'mah':'mh', 'mri':'mi', 'mkd':'mk', \ + 'mal':'ml', 'mon':'mn', 'mar':'mr', 'msa':'ms', 'mlt':'mt', 'mya':'my', \ + 'nau':'na', 'nob':'nb', 'nde':'nd', 'nep':'ne', 'ndo':'ng', 'nld':'nl', \ + 'nno':'nn', 'nor':'no', 'nbl':'nr', 'nav':'nv', 'nya':'ny', 'oci':'oc', \ + 'oji':'oj', 'orm':'om', 'ori':'or', 'oss':'os', 'pan':'pa', 'pli':'pi', \ + 'pol':'pl', 'pus':'ps', 'por':'pt', 'que':'qu', 'roh':'rm', 'run':'rn', \ + 'ron':'ro', 'rus':'ru', 'kin':'rw', 'san':'sa', 'srd':'sc', 'snd':'sd', \ + 'sme':'se', 'sag':'sg', 'sin':'si', 'slk':'sk', 'slv':'sl', 'smo':'sm', \ + 'sna':'sn', 'som':'so', 'sqi':'sq', 'srp':'sr', 'ssw':'ss', 'sot':'st', \ + 'sun':'su', 'swe':'sv', 'swa':'sw', 'tam':'ta', 'tel':'te', 'tgk':'tg', \ + 'tha':'th', 'tir':'ti', 'tuk':'tk', 'tgl':'tl', 'tsn':'tn', 'ton':'to', \ + 'tur':'tr', 'tso':'ts', 'tat':'tt', 'twi':'tw', 'tah':'ty', 'uig':'ug', \ + 'ukr':'uk', 'urd':'ur', 'uzb':'uz', 'ven':'ve', 'vie':'vi', 'vol':'vo', \ + 'wln':'wa', 'wol':'wo', 'xho':'xh', 'yid':'yi', 'yor':'yo', 'zha':'za', \ + 'zho':'zh', 'zul':'zu'} + +## GetLanguageCode +# +# Check the language code read from .UNI file and convert ISO 639-2 codes to RFC 4646 codes if appropriate +# ISO 639-2 language codes supported in compatiblity mode +# RFC 4646 language codes supported in native mode +# +# @param LangName: Language codes read from .UNI file +# +# @retval LangName: Valid lanugage code in RFC 4646 format or None +# +def GetLanguageCode(LangName, IsCompatibleMode, File): + global LangConvTable + + length = len(LangName) + if IsCompatibleMode: + if length == 3 and LangName.isalpha(): + TempLangName = LangConvTable.get(LangName.lower()) + if TempLangName != None: + return TempLangName + return LangName + else: + EdkLogger.error("Unicode File Parser", FORMAT_INVALID, "Invalid ISO 639-2 language code : %s" % LangName, File) + + if length == 2: + if LangName.isalpha(): + return LangName + elif length == 3: + if LangName.isalpha() and LangConvTable.get(LangName.lower()) == None: + return LangName + elif length == 5: + if LangName[0:2].isalpha() and LangName[2] == '-': + return LangName + elif length >= 6: + if LangName[0:2].isalpha() and LangName[2] == '-': + return LangName + if LangName[0:3].isalpha() and LangConvTable.get(LangName.lower()) == None and LangName[3] == '-': + return LangName + + EdkLogger.error("Unicode File Parser", FORMAT_INVALID, "Invalid RFC 4646 language code : %s" % LangName, File) + +## StringDefClassObject +# +# A structure for language definition +# +class StringDefClassObject(object): + def __init__(self, Name = None, Value = None, Referenced = False, Token = None, UseOtherLangDef = ''): + self.StringName = '' + self.StringNameByteList = [] + self.StringValue = '' + self.StringValueByteList = '' + self.Token = 0 + self.Referenced = Referenced + self.UseOtherLangDef = UseOtherLangDef + self.Length = 0 + + if Name != None: + self.StringName = Name + self.StringNameByteList = UniToHexList(Name) + if Value != None: + self.StringValue = Value + u'\x00' # Add a NULL at string tail + self.StringValueByteList = UniToHexList(self.StringValue) + self.Length = len(self.StringValueByteList) + if Token != None: + self.Token = Token + + def __str__(self): + return repr(self.StringName) + ' ' + \ + repr(self.Token) + ' ' + \ + repr(self.Referenced) + ' ' + \ + repr(self.StringValue) + ' ' + \ + repr(self.UseOtherLangDef) + +## UniFileClassObject +# +# A structure for .uni file definition +# +class UniFileClassObject(object): + def __init__(self, FileList = [], IsCompatibleMode = False): + self.FileList = FileList + self.Token = 2 + self.LanguageDef = [] #[ [u'LanguageIdentifier', u'PrintableName'], ... ] + self.OrderedStringList = {} #{ u'LanguageIdentifier' : [StringDefClassObject] } + self.IsCompatibleMode = IsCompatibleMode + + if len(self.FileList) > 0: + self.LoadUniFiles(FileList) + + # + # Get Language definition + # + def GetLangDef(self, File, Line): + Lang = Line.split() + if len(Lang) != 3: + try: + FileIn = codecs.open(File, mode='rb', encoding='utf-16').read() + except UnicodeError, X: + EdkLogger.error("build", FILE_READ_FAILURE, "File read failure: %s" % str(X), ExtraData=File); + except: + EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=File); + LineNo = GetLineNo(FileIn, Line, False) + EdkLogger.error("Unicode File Parser", PARSER_ERROR, "Wrong language definition", + ExtraData="""%s\n\t*Correct format is like '#langdef eng "English"'""" % Line, File = File, Line = LineNo) + else: + LangName = GetLanguageCode(Lang[1], self.IsCompatibleMode, self.File) + LangPrintName = Lang[2][1:-1] + + IsLangInDef = False + for Item in self.LanguageDef: + if Item[0] == LangName: + IsLangInDef = True + break; + + if not IsLangInDef: + self.LanguageDef.append([LangName, LangPrintName]) + + # + # Add language string + # + self.AddStringToList(u'$LANGUAGE_NAME', LangName, LangName, 0, True, Index=0) + self.AddStringToList(u'$PRINTABLE_LANGUAGE_NAME', LangName, LangPrintName, 1, True, Index=1) + + return True + + # + # Get String name and value + # + def GetStringObject(self, Item): + Name = '' + Language = '' + Value = '' + + Name = Item.split()[1] + LanguageList = Item.split(u'#language ') + for IndexI in range(len(LanguageList)): + if IndexI == 0: + continue + else: + Language = LanguageList[IndexI].split()[0] + Value = LanguageList[IndexI][LanguageList[IndexI].find(u'\"') + len(u'\"') : LanguageList[IndexI].rfind(u'\"')] #.replace(u'\r\n', u'') + Language = GetLanguageCode(Language, self.IsCompatibleMode, self.File) + self.AddStringToList(Name, Language, Value) + + # + # Get include file list and load them + # + def GetIncludeFile(self, Item, Dir): + FileName = Item[Item.find(u'#include ') + len(u'#include ') :Item.find(u' ', len(u'#include '))][1:-1] + self.LoadUniFile(FileName) + + # + # Pre-process before parse .uni file + # + def PreProcess(self, File): + if not os.path.exists(File.Path) or not os.path.isfile(File.Path): + EdkLogger.error("Unicode File Parser", FILE_NOT_FOUND, ExtraData=File.Path) + + Dir = File.Dir + try: + FileIn = codecs.open(File.Path, mode='rb', encoding='utf-16').readlines() + except UnicodeError, X: + EdkLogger.error("build", FILE_READ_FAILURE, "File read failure: %s" % str(X), ExtraData=File.Path); + except: + EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=File.Path); + + Lines = [] + # + # Use unique identifier + # + for Line in FileIn: + Line = Line.strip() + # + # Ignore comment line and empty line + # + if Line == u'' or Line.startswith(u'//'): + continue + Line = Line.replace(u'/langdef', u'#langdef') + Line = Line.replace(u'/string', u'#string') + Line = Line.replace(u'/language', u'#language') + Line = Line.replace(u'/include', u'#include') + + Line = Line.replace(UNICODE_WIDE_CHAR, WIDE_CHAR) + Line = Line.replace(UNICODE_NARROW_CHAR, NARROW_CHAR) + Line = Line.replace(UNICODE_NON_BREAKING_CHAR, NON_BREAKING_CHAR) + + Line = Line.replace(u'\\\\', u'\u0006') + Line = Line.replace(u'\\r\\n', CR + LF) + Line = Line.replace(u'\\n', CR + LF) + Line = Line.replace(u'\\r', CR) + Line = Line.replace(u'\\t', u'\t') + Line = Line.replace(u'''\"''', u'''"''') + Line = Line.replace(u'\t', u' ') + Line = Line.replace(u'\u0006', u'\\') + +# if Line.find(u'\\x'): +# hex = Line[Line.find(u'\\x') + 2 : Line.find(u'\\x') + 6] +# hex = "u'\\u" + hex + "'" + + IncList = gIncludePattern.findall(Line) + if len(IncList) == 1: + Lines.extend(self.PreProcess(PathClass(str(IncList[0]), Dir))) + continue + + Lines.append(Line) + + return Lines + + # + # Load a .uni file + # + def LoadUniFile(self, File = None): + if File == None: + EdkLogger.error("Unicode File Parser", PARSER_ERROR, 'No unicode file is given') + self.File = File + # + # Process special char in file + # + Lines = self.PreProcess(File) + + # + # Get Unicode Information + # + for IndexI in range(len(Lines)): + Line = Lines[IndexI] + if (IndexI + 1) < len(Lines): + SecondLine = Lines[IndexI + 1] + if (IndexI + 2) < len(Lines): + ThirdLine = Lines[IndexI + 2] + + # + # Get Language def information + # + if Line.find(u'#langdef ') >= 0: + self.GetLangDef(File, Line) + continue + + Name = '' + Language = '' + Value = '' + # + # Get string def information format 1 as below + # + # #string MY_STRING_1 + # #language eng + # My first English string line 1 + # My first English string line 2 + # #string MY_STRING_1 + # #language spa + # Mi segunda secuencia 1 + # Mi segunda secuencia 2 + # + if Line.find(u'#string ') >= 0 and Line.find(u'#language ') < 0 and \ + SecondLine.find(u'#string ') < 0 and SecondLine.find(u'#language ') >= 0 and \ + ThirdLine.find(u'#string ') < 0 and ThirdLine.find(u'#language ') < 0: + Name = Line[Line.find(u'#string ') + len(u'#string ') : ].strip(' ') + Language = SecondLine[SecondLine.find(u'#language ') + len(u'#language ') : ].strip(' ') + for IndexJ in range(IndexI + 2, len(Lines)): + if Lines[IndexJ].find(u'#string ') < 0 and Lines[IndexJ].find(u'#language ') < 0: + Value = Value + Lines[IndexJ] + else: + IndexI = IndexJ + break + # Value = Value.replace(u'\r\n', u'') + Language = GetLanguageCode(Language, self.IsCompatibleMode, self.File) + self.AddStringToList(Name, Language, Value) + continue + + # + # Get string def information format 2 as below + # + # #string MY_STRING_1 #language eng "My first English string line 1" + # "My first English string line 2" + # #language spa "Mi segunda secuencia 1" + # "Mi segunda secuencia 2" + # #string MY_STRING_2 #language eng "My first English string line 1" + # "My first English string line 2" + # #string MY_STRING_2 #language spa "Mi segunda secuencia 1" + # "Mi segunda secuencia 2" + # + if Line.find(u'#string ') >= 0 and Line.find(u'#language ') >= 0: + StringItem = Line + for IndexJ in range(IndexI + 1, len(Lines)): + if Lines[IndexJ].find(u'#string ') >= 0 and Lines[IndexJ].find(u'#language ') >= 0: + IndexI = IndexJ + break + elif Lines[IndexJ].find(u'#string ') < 0 and Lines[IndexJ].find(u'#language ') >= 0: + StringItem = StringItem + Lines[IndexJ] + elif Lines[IndexJ].count(u'\"') >= 2: + StringItem = StringItem[ : StringItem.rfind(u'\"')] + Lines[IndexJ][Lines[IndexJ].find(u'\"') + len(u'\"') : ] + self.GetStringObject(StringItem) + continue + + # + # Load multiple .uni files + # + def LoadUniFiles(self, FileList = []): + if len(FileList) > 0: + if len(FileList) > 1: + NewList = []; + for File in FileList: + NewList.append (File) + NewList.sort() + for File in NewList: + self.LoadUniFile(File) + else: + for File in FileList: + self.LoadUniFile(File) + + # + # Add a string to list + # + def AddStringToList(self, Name, Language, Value, Token = None, Referenced = False, UseOtherLangDef = '', Index = -1): + if Language not in self.OrderedStringList: + self.OrderedStringList[Language] = [] + + IsAdded = False + for Item in self.OrderedStringList[Language]: + if Name == Item.StringName: + IsAdded = True + break + if not IsAdded: + Token = len(self.OrderedStringList[Language]) + if Index == -1: + self.OrderedStringList[Language].append(StringDefClassObject(Name, Value, Referenced, Token, UseOtherLangDef)) + else: + self.OrderedStringList[Language].insert(Index, StringDefClassObject(Name, Value, Referenced, Token, UseOtherLangDef)) + + # + # Set the string as referenced + # + def SetStringReferenced(self, Name): + for Lang in self.OrderedStringList: + for Item in self.OrderedStringList[Lang]: + if Name == Item.StringName: + Item.Referenced = True + break + # + # Search the string in language definition by Name + # + def FindStringValue(self, Name, Lang): + for Item in self.OrderedStringList[Lang]: + if Item.StringName == Name: + return Item + + return None + + # + # Search the string in language definition by Token + # + def FindByToken(self, Token, Lang): + for Item in self.OrderedStringList[Lang]: + if Item.Token == Token: + return Item + + return None + + # + # Re-order strings and re-generate tokens + # + def ReToken(self): + # + # Search each string to find if it is defined for each language + # Use secondary language value to replace if missing in any one language + # + for IndexI in range(0, len(self.LanguageDef)): + LangKey = self.LanguageDef[IndexI][0] + for Item in self.OrderedStringList[LangKey]: + Name = Item.StringName + Value = Item.StringValue[0:-1] + Referenced = Item.Referenced + Index = self.OrderedStringList[LangKey].index(Item) + for IndexJ in range(0, len(self.LanguageDef)): + LangFind = self.LanguageDef[IndexJ][0] + if self.FindStringValue(Name, LangFind) == None: + EdkLogger.debug(EdkLogger.DEBUG_5, Name) + Token = len(self.OrderedStringList[LangFind]) + self.AddStringToList(Name, LangFind, Value, Token, Referenced, LangKey, Index) + + # + # Retoken + # + # First re-token the first language + LangName = self.LanguageDef[0][0] + ReferencedStringList = [] + NotReferencedStringList = [] + Token = 0 + for Item in self.OrderedStringList[LangName]: + if Item.Referenced == True: + Item.Token = Token + ReferencedStringList.append(Item) + Token = Token + 1 + else: + NotReferencedStringList.append(Item) + self.OrderedStringList[LangName] = ReferencedStringList + for Index in range(len(NotReferencedStringList)): + NotReferencedStringList[Index].Token = Token + Index + self.OrderedStringList[LangName].append(NotReferencedStringList[Index]) + + # + # Adjust the orders of other languages + # + for IndexOfLanguage in range(1, len(self.LanguageDef)): + for OrderedString in self.OrderedStringList[LangName]: + for UnOrderedString in self.OrderedStringList[self.LanguageDef[IndexOfLanguage][0]]: + if OrderedString.StringName == UnOrderedString.StringName: + UnOrderedString.Token = OrderedString.Token + break + + # + # Show the instance itself + # + def ShowMe(self): + print self.LanguageDef + #print self.OrderedStringList + for Item in self.OrderedStringList: + print Item + for Member in self.OrderedStringList[Item]: + print str(Member) + +# 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) + a = UniFileClassObject(['C:\\Edk\\Strings.uni', 'C:\\Edk\\Strings2.uni']) + a.ReToken() + a.ShowMe() diff --git a/BaseTools/Source/Python/AutoGen/__init__.py b/BaseTools/Source/Python/AutoGen/__init__.py new file mode 100644 index 0000000000..d6fa5ec126 --- /dev/null +++ b/BaseTools/Source/Python/AutoGen/__init__.py @@ -0,0 +1,10 @@ +# Copyright (c) 2007, 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 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. + +__all__ = ["AutoGen"] diff --git a/BaseTools/Source/Python/Common/BuildToolError.py b/BaseTools/Source/Python/Common/BuildToolError.py new file mode 100644 index 0000000000..982ea93659 --- /dev/null +++ b/BaseTools/Source/Python/Common/BuildToolError.py @@ -0,0 +1,152 @@ +## @file +# Standardized Error Hanlding infrastructures. +# +# Copyright (c) 2007, 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 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_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_UNKNOWN_ERROR = 0x5FFF + +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 +ABORT_ERROR = 0xFFFE +UNKNOWN_ERROR = 0xFFFF + +## Error message of each error code +gErrorMessage = { + FILE_NOT_FOUND : "File/directory not found", + FILE_OPEN_FAILURE : "File open failure", + FILE_WRITE_FAILURE : "File write failure", + FILE_PARSE_FAILURE : "File parse failure", + FILE_READ_FAILURE : "File read failure", + FILE_CREATE_FAILURE : "File create failure", + FILE_CHECKSUM_FAILURE : "Invalid checksum of file", + FILE_COMPRESS_FAILURE : "File compress failure", + FILE_DECOMPRESS_FAILURE : "File decompress failure", + FILE_MOVE_FAILURE : "File move failure", + FILE_DELETE_FAILURE : "File delete failure", + FILE_COPY_FAILURE : "File copy failure", + FILE_POSITIONING_FAILURE: "Failed to seeking position", + FILE_ALREADY_EXIST : "File or directory already exists", + FILE_TYPE_MISMATCH : "Incorrect file type", + FILE_CASE_MISMATCH : "File name case mismatch", + FILE_DUPLICATED : "Duplicated file found", + FILE_UNKNOWN_ERROR : "Unknown error encountered on file", + + OPTION_UNKNOWN : "Unknown option", + OPTION_MISSING : "Missing option", + OPTION_CONFLICT : "Conflict options", + OPTION_VALUE_INVALID : "Invalid value of option", + OPTION_DEPRECATED : "Deprecated option", + OPTION_NOT_SUPPORTED : "Unsupported option", + OPTION_UNKNOWN_ERROR : "Unknown error when processing options", + + PARAMETER_INVALID : "Invalid parameter", + PARAMETER_MISSING : "Missing parameter", + PARAMETER_UNKNOWN_ERROR : "Unknown error in parameters", + + FORMAT_INVALID : "Invalid syntax/format", + FORMAT_NOT_SUPPORTED : "Not supported syntax/format", + FORMAT_UNKNOWN : "Unknown format", + FORMAT_UNKNOWN_ERROR : "Unknown error in syntax/format ", + + RESOURCE_NOT_AVAILABLE : "Not available", + RESOURCE_ALLOCATE_FAILURE : "Allocate failure", + RESOURCE_FULL : "Full", + RESOURCE_OVERFLOW : "Overflow", + RESOURCE_UNDERRUN : "Underrun", + RESOURCE_UNKNOWN_ERROR : "Unkown error", + + ATTRIBUTE_NOT_AVAILABLE : "Not available", + ATTRIBUTE_GET_FAILURE : "Failed to retrieve", + ATTRIBUTE_SET_FAILURE : "Failed to set", + ATTRIBUTE_UPDATE_FAILURE: "Failed to update", + ATTRIBUTE_ACCESS_DENIED : "Access denied", + ATTRIBUTE_UNKNOWN_ERROR : "Unknown error when accessing", + + COMMAND_FAILURE : "Failed to execute command", + + IO_NOT_READY : "Not ready", + IO_BUSY : "Busy", + IO_TIMEOUT : "Timeout", + IO_UNKNOWN_ERROR : "Unknown error in IO operation", + + UNKNOWN_ERROR : "Unknown error", +} + +## Exception indicating a fatal error +class FatalError(Exception): + pass + +if __name__ == "__main__": + pass diff --git a/BaseTools/Source/Python/Common/DataType.py b/BaseTools/Source/Python/Common/DataType.py new file mode 100644 index 0000000000..8b6c4e4921 --- /dev/null +++ b/BaseTools/Source/Python/Common/DataType.py @@ -0,0 +1,401 @@ +## @file +# This file is used to define common static strings used by INF/DEC/DSC files +# +# Copyright (c) 2007 ~ 2008, 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 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 Definitions +# +TAB_SPLIT = '.' +TAB_COMMENT_R8_START = '/*' +TAB_COMMENT_R8_END = '*/' +TAB_COMMENT_R8_SPLIT = '//' +TAB_COMMENT_SPLIT = '#' +TAB_EQUAL_SPLIT = '=' +TAB_VALUE_SPLIT = '|' +TAB_COMMA_SPLIT = ',' +TAB_SPACE_SPLIT = ' ' +TAB_SECTION_START = '[' +TAB_SECTION_END = ']' +TAB_OPTION_START = '<' +TAB_OPTION_END = '>' +TAB_SLASH = '\\' +TAB_BACK_SLASH = '/' + +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] +ARCH_LIST_FULL = [TAB_ARCH_COMMON] + ARCH_LIST + +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_DRIVER = 'SMM_DRIVER' +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_DRIVER, 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' + +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_UNI_VER = 'UNI_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_TE = 'TE' +BINARY_FILE_TYPE_VER = 'VER' +BINARY_FILE_TYPE_UI = 'UI' +BINARY_FILE_TYPE_BIN = 'BIN' +BINARY_FILE_TYPE_FV = 'FV' + +PLATFORM_COMPONENT_TYPE_LIBRARY = 'LIBRARY' +PLATFORM_COMPONENT_TYPE_LIBRARY_CLASS = 'LIBRARY_CLASS' +PLATFORM_COMPONENT_TYPE_MODULE = 'MODULE' + +TAB_LIBRARIES = 'Libraries' + +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' + +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 +gDynamicExPcd = [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_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_VERSION_NUMBER = 'VERSION_NUMBER' +TAB_INF_DEFINES_VERSION = 'VERSION' # for R8 inf, the same as VERSION_NUMBER +TAB_INF_DEFINES_VERSION_STRING = 'VERSION_STRING' +TAB_INF_DEFINES_PCD_IS_DRIVER = 'PCD_IS_DRIVER' +TAB_INF_DEFINES_TIANO_R8_FLASHMAP_H = 'TIANO_R8_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_DEFINE = 'DEFINE' +TAB_INF_DEFINES_SPEC = 'SPEC' +TAB_INF_DEFINES_CUSTOM_MAKEFILE = 'CUSTOM_MAKEFILE' +TAB_INF_DEFINES_MACRO = '__MACROS__' +TAB_INF_DEFINES_SHADOW = 'SHADOW' +TAB_INF_FIXED_PCD = 'FixedPcd' +TAB_INF_FEATURE_PCD = 'FeaturePcd' +TAB_INF_PATCH_PCD = 'PatchPcd' +TAB_INF_PCD = 'Pcd' +TAB_INF_PCD_EX = 'PcdEx' + +# +# 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' + +# +# 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' + +# +# 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' + +# +# Build database path +# +DATABASE_PATH = ":memory:" #"BuildDatabase.db" + +# 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_" + diff --git a/BaseTools/Source/Python/Common/Database.py b/BaseTools/Source/Python/Common/Database.py new file mode 100644 index 0000000000..e645337a39 --- /dev/null +++ b/BaseTools/Source/Python/Common/Database.py @@ -0,0 +1,120 @@ +## @file +# This file is used to create a database used by ECC tool +# +# Copyright (c) 2007 ~ 2008, 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 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 EdkLogger as EdkLogger +from CommonDataClass.DataClass import * +from String import * +from DataType import * + +from Table.TableDataModel import TableDataModel +from Table.TableFile import TableFile +from Table.TableInf import TableInf +from Table.TableDec import TableDec +from Table.TableDsc import TableDsc + +## Database +# +# This class defined the build databse +# During the phase of initialization, the database will create all tables and +# insert all records of table DataModel +# +# @param object: Inherited from object class +# @param DbPath: A string for the path of the ECC database +# +# @var Conn: Connection of the ECC database +# @var Cur: Cursor of the connection +# @var TblDataModel: Local instance for TableDataModel +# +class Database(object): + def __init__(self, DbPath): + if os.path.exists(DbPath): + os.remove(DbPath) + self.Conn = sqlite3.connect(DbPath, isolation_level = 'DEFERRED') + self.Conn.execute("PRAGMA page_size=8192") + self.Conn.execute("PRAGMA synchronous=OFF") + self.Cur = self.Conn.cursor() + self.TblDataModel = TableDataModel(self.Cur) + self.TblFile = TableFile(self.Cur) + self.TblInf = TableInf(self.Cur) + self.TblDec = TableDec(self.Cur) + self.TblDsc = TableDsc(self.Cur) + + ## Initialize build database + # + # 1. Delete all old existing tables + # 2. Create new tables + # 3. Initialize table DataModel + # + def InitDatabase(self): + EdkLogger.verbose("\nInitialize ECC database started ...") + # + # Drop all old existing tables + # +# self.TblDataModel.Drop() +# self.TblDsc.Drop() +# self.TblFile.Drop() + + # + # Create new tables + # + self.TblDataModel.Create() + self.TblFile.Create() + self.TblInf.Create() + self.TblDec.Create() + self.TblDsc.Create() + + # + # Initialize table DataModel + # + self.TblDataModel.InitTable() + EdkLogger.verbose("Initialize ECC database ... DONE!") + + ## Query a table + # + # @param Table: The instance of the table to be queried + # + def QueryTable(self, Table): + Table.Query() + + ## Close entire database + # + # Commit all first + # Close the connection and cursor + # + def Close(self): + self.Conn.commit() + self.Cur.close() + self.Conn.close() + +## +# +# 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) + + Db = Database(DATABASE_PATH) + Db.InitDatabase() + Db.QueryTable(Db.TblDataModel) + Db.QueryTable(Db.TblFile) + Db.QueryTable(Db.TblDsc) + Db.Close() + \ No newline at end of file diff --git a/BaseTools/Source/Python/Common/DecClassObject.py b/BaseTools/Source/Python/Common/DecClassObject.py new file mode 100644 index 0000000000..b95ff621cc --- /dev/null +++ b/BaseTools/Source/Python/Common/DecClassObject.py @@ -0,0 +1,563 @@ +## @file +# This file is used to define each component of DEC file +# +# Copyright (c) 2007, 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 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 +from String import * +from DataType import * +from Identification import * +from Dictionary import * +from CommonDataClass.PackageClass import * +from CommonDataClass.CommonClass import PcdClass +from BuildToolError import * +from Table.TableDec import TableDec +import Database +from Parsing import * +import GlobalData + +# +# Global variable +# +Section = {TAB_UNKNOWN.upper() : MODEL_UNKNOWN, + TAB_DEC_DEFINES.upper() : MODEL_META_DATA_HEADER, + TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE, + TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS, + TAB_COMPONENTS.upper() : MODEL_META_DATA_COMPONENT, + TAB_GUIDS.upper() : MODEL_EFI_GUID, + TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL, + TAB_PPIS.upper() : MODEL_EFI_PPI, + TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : MODEL_PCD_FIXED_AT_BUILD, + TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : MODEL_PCD_PATCHABLE_IN_MODULE, + TAB_PCDS_FEATURE_FLAG_NULL.upper() : MODEL_PCD_FEATURE_FLAG, + TAB_PCDS_DYNAMIC_EX_NULL.upper() : MODEL_PCD_DYNAMIC_EX, + TAB_PCDS_DYNAMIC_NULL.upper() : MODEL_PCD_DYNAMIC, + TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION + } + + +## DecObject +# +# This class defined basic Dec object which is used by inheriting +# +# @param object: Inherited from object class +# +class DecObject(object): + def __init__(self): + object.__init__() + +## Dec +# +# This class defined the structure used in Dec object +# +# @param DecObject: Inherited from DecObject class +# @param Filename: Input value for Filename of Dec file, default is None +# @param IsMergeAllArches: Input value for IsMergeAllArches +# True is to merge all arches +# Fales is not to merge all arches +# default is False +# @param IsToPackage: Input value for IsToPackage +# True is to transfer to PackageObject automatically +# False is not to transfer to PackageObject automatically +# default is False +# @param WorkspaceDir: Input value for current workspace directory, default is None +# +# @var Identification: To store value for Identification, it is a structure as Identification +# @var Defines: To store value for Defines, it is a structure as DecDefines +# @var UserExtensions: To store value for UserExtensions +# @var Package: To store value for Package, it is a structure as PackageClass +# @var WorkspaceDir: To store value for WorkspaceDir +# @var Contents: To store value for Contents, it is a structure as DecContents +# @var KeyList: To store value for KeyList, a list for all Keys used in Dec +# +class Dec(DecObject): + def __init__(self, Filename = None, IsToDatabase = False, IsToPackage = False, WorkspaceDir = None, Database = None, SupArchList = DataType.ARCH_LIST): + self.Identification = Identification() + self.Package = PackageClass() + self.UserExtensions = '' + self.WorkspaceDir = WorkspaceDir + self.SupArchList = SupArchList + self.IsToDatabase = IsToDatabase + + self.Cur = Database.Cur + self.TblFile = Database.TblFile + self.TblDec = Database.TblDec + self.FileID = -1 + + self.KeyList = [ + TAB_INCLUDES, TAB_GUIDS, TAB_PROTOCOLS, TAB_PPIS, TAB_LIBRARY_CLASSES, \ + TAB_PCDS_FIXED_AT_BUILD_NULL, TAB_PCDS_PATCHABLE_IN_MODULE_NULL, TAB_PCDS_FEATURE_FLAG_NULL, \ + TAB_PCDS_DYNAMIC_NULL, TAB_PCDS_DYNAMIC_EX_NULL, TAB_DEC_DEFINES + ] + # + # Upper all KEYs to ignore case sensitive when parsing + # + self.KeyList = map(lambda c: c.upper(), self.KeyList) + + # + # Init RecordSet + # + self.RecordSet = {} + for Key in self.KeyList: + self.RecordSet[Section[Key]] = [] + + # + # Load Dec file if filename is not None + # + if Filename != None: + self.LoadDecFile(Filename) + + # + # Transfer to Package Object if IsToPackage is True + # + if IsToPackage: + self.DecToPackage() + + ## Load Dec file + # + # Load the file if it exists + # + # @param Filename: Input value for filename of Dec file + # + def LoadDecFile(self, Filename): + # + # Insert a record for file + # + Filename = NormPath(Filename) + self.Identification.FileFullPath = Filename + (self.Identification.FileRelativePath, self.Identification.FileName) = os.path.split(Filename) + self.FileID = self.TblFile.InsertFile(Filename, MODEL_FILE_DEC) + + # + # Init DecTable + # + #self.TblDec.Table = "Dec%s" % self.FileID + #self.TblDec.Create() + + # + # Init common datas + # + IfDefList, SectionItemList, CurrentSection, ArchList, ThirdList, IncludeFiles = \ + [], [], TAB_UNKNOWN, [], [], [] + LineNo = 0 + + # + # Parse file content + # + IsFindBlockComment = False + ReservedLine = '' + for Line in open(Filename, 'r'): + LineNo = LineNo + 1 + # + # Remove comment block + # + if Line.find(TAB_COMMENT_R8_START) > -1: + ReservedLine = GetSplitValueList(Line, TAB_COMMENT_R8_START, 1)[0] + IsFindBlockComment = True + if Line.find(TAB_COMMENT_R8_END) > -1: + Line = ReservedLine + GetSplitValueList(Line, TAB_COMMENT_R8_END, 1)[1] + ReservedLine = '' + IsFindBlockComment = False + if IsFindBlockComment: + continue + + # + # Remove comments at tail and remove spaces again + # + Line = CleanString(Line) + if Line == '': + continue + + # + # Find a new section tab + # First insert previous section items + # And then parse the content of the new section + # + if Line.startswith(TAB_SECTION_START) and Line.endswith(TAB_SECTION_END): + # + # Insert items data of previous section + # + Model = Section[CurrentSection.upper()] + InsertSectionItemsIntoDatabase(self.TblDec, self.FileID, Filename, Model, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList, self.RecordSet) + + # + # Parse the new section + # + SectionItemList = [] + ArchList = [] + ThirdList = [] + + CurrentSection = '' + LineList = GetSplitValueList(Line[len(TAB_SECTION_START):len(Line) - len(TAB_SECTION_END)], TAB_COMMA_SPLIT) + for Item in LineList: + ItemList = GetSplitValueList(Item, TAB_SPLIT) + if CurrentSection == '': + CurrentSection = ItemList[0] + else: + if CurrentSection != ItemList[0]: + EdkLogger.error("Parser", PARSER_ERROR, "Different section names '%s' and '%s' are found in one section definition, this is not allowed." % (CurrentSection, ItemList[0]), File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError) + if CurrentSection.upper() not in self.KeyList: + RaiseParserError(Line, CurrentSection, Filename, '', LineNo) + ItemList.append('') + ItemList.append('') + if len(ItemList) > 5: + RaiseParserError(Line, CurrentSection, Filename, '', LineNo) + else: + if ItemList[1] != '' and ItemList[1].upper() not in ARCH_LIST_FULL: + EdkLogger.error("Parser", PARSER_ERROR, "Invalid Arch definition '%s' found" % ItemList[1], File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError) + ArchList.append(ItemList[1].upper()) + ThirdList.append(ItemList[2]) + + continue + + # + # Not in any defined section + # + if CurrentSection == TAB_UNKNOWN: + ErrorMsg = "%s is not in any defined section" % Line + EdkLogger.error("Parser", PARSER_ERROR, ErrorMsg, File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError) + + # + # Add a section item + # + SectionItemList.append([Line, LineNo]) + # End of parse + #End of For + + # + # Insert items data of last section + # + Model = Section[CurrentSection.upper()] + InsertSectionItemsIntoDatabase(self.TblDec, self.FileID, Filename, Model, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList, self.RecordSet) + + # + # Replace all DEFINE macros with its actual values + # + ParseDefineMacro2(self.TblDec, self.RecordSet, GlobalData.gGlobalDefines) + + ## Transfer to Package Object + # + # Transfer all contents of a Dec file to a standard Package Object + # + def DecToPackage(self): + # + # Init global information for the file + # + ContainerFile = self.Identification.FileFullPath + + # + # Generate Package Header + # + self.GenPackageHeader(ContainerFile) + + # + # Generate Includes + # + self.GenIncludes(ContainerFile) + + # + # Generate Guids + # + self.GenGuidProtocolPpis(DataType.TAB_GUIDS, ContainerFile) + + # + # Generate Protocols + # + self.GenGuidProtocolPpis(DataType.TAB_PROTOCOLS, ContainerFile) + + # + # Generate Ppis + # + self.GenGuidProtocolPpis(DataType.TAB_PPIS, ContainerFile) + + # + # Generate LibraryClasses + # + self.GenLibraryClasses(ContainerFile) + + # + # Generate Pcds + # + self.GenPcds(ContainerFile) + + ## Get Package Header + # + # Gen Package Header of Dec as = + # + # @param ContainerFile: The Dec file full path + # + def GenPackageHeader(self, ContainerFile): + EdkLogger.debug(2, "Generate PackageHeader ...") + # + # Update all defines item in database + # + RecordSet = self.RecordSet[MODEL_META_DATA_HEADER] + for Record in RecordSet: + ValueList = GetSplitValueList(Record[0], TAB_EQUAL_SPLIT) + if len(ValueList) != 2: + RaiseParserError(Record[0], 'Defines', ContainerFile, ' = ', Record[2]) + ID, Value1, Value2, Arch, LineNo = Record[3], ValueList[0], ValueList[1], Record[1], Record[2] + SqlCommand = """update %s set Value1 = '%s', Value2 = '%s' + where ID = %s""" % (self.TblDec.Table, ConvertToSqlString2(Value1), ConvertToSqlString2(Value2), ID) + self.TblDec.Exec(SqlCommand) + + # + # Get detailed information + # + for Arch in self.SupArchList: + PackageHeader = PackageHeaderClass() + + PackageHeader.Name = QueryDefinesItem(self.TblDec, TAB_DEC_DEFINES_PACKAGE_NAME, Arch, self.FileID)[0] + PackageHeader.Guid = QueryDefinesItem(self.TblDec, TAB_DEC_DEFINES_PACKAGE_GUID, Arch, self.FileID)[0] + PackageHeader.Version = QueryDefinesItem(self.TblDec, TAB_DEC_DEFINES_PACKAGE_VERSION, Arch, self.FileID)[0] + PackageHeader.FileName = self.Identification.FileName + PackageHeader.FullPath = self.Identification.FileFullPath + PackageHeader.DecSpecification = QueryDefinesItem(self.TblDec, TAB_DEC_DEFINES_DEC_SPECIFICATION, Arch, self.FileID)[0] + + self.Package.Header[Arch] = PackageHeader + + ## GenIncludes + # + # Gen Includes of Dec + # + # + # @param ContainerFile: The Dec file full path + # + def GenIncludes(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_INCLUDES) + Includes = {} + # + # Get all Includes + # + RecordSet = self.RecordSet[MODEL_EFI_INCLUDE] + + # + # Go through each arch + # + for Arch in self.SupArchList: + for Record in RecordSet: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: + MergeArches(Includes, Record[0], Arch) + + for Key in Includes.keys(): + Include = IncludeClass() + Include.FilePath = NormPath(Key) + Include.SupArchList = Includes[Key] + self.Package.Includes.append(Include) + + ## GenPpis + # + # Gen Ppis of Dec + # = + # + # @param ContainerFile: The Dec file full path + # + def GenGuidProtocolPpis(self, Type, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % Type) + Lists = {} + # + # Get all Items + # + RecordSet = self.RecordSet[Section[Type.upper()]] + + # + # Go through each arch + # + for Arch in self.SupArchList: + for Record in RecordSet: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: + (Name, Value) = GetGuidsProtocolsPpisOfDec(Record[0], Type, ContainerFile, Record[2]) + MergeArches(Lists, (Name, Value), Arch) + if self.IsToDatabase: + SqlCommand = """update %s set Value1 = '%s', Value2 = '%s' + where ID = %s""" % (self.TblDec.Table, ConvertToSqlString2(Name), ConvertToSqlString2(Value), Record[3]) + self.TblDec.Exec(SqlCommand) + + ListMember = None + if Type == TAB_GUIDS: + ListMember = self.Package.GuidDeclarations + elif Type == TAB_PROTOCOLS: + ListMember = self.Package.ProtocolDeclarations + elif Type == TAB_PPIS: + ListMember = self.Package.PpiDeclarations + + for Key in Lists.keys(): + ListClass = GuidProtocolPpiCommonClass() + ListClass.CName = Key[0] + ListClass.Guid = Key[1] + ListClass.SupArchList = Lists[Key] + ListMember.append(ListClass) + + + ## GenLibraryClasses + # + # Gen LibraryClasses of Dec + # = + # + # @param ContainerFile: The Dec file full path + # + def GenLibraryClasses(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_LIBRARY_CLASSES) + LibraryClasses = {} + # + # Get all Guids + # + RecordSet = self.RecordSet[MODEL_EFI_LIBRARY_CLASS] + + # + # Go through each arch + # + for Arch in self.SupArchList: + for Record in RecordSet: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: + List = GetSplitValueList(Record[0], DataType.TAB_VALUE_SPLIT) + if len(List) != 2: + RaiseParserError(Record[0], 'LibraryClasses', ContainerFile, '|', Record[2]) + else: + CheckFileExist(self.Identification.FileRelativePath, List[1], ContainerFile, 'LibraryClasses', Record[0]) + MergeArches(LibraryClasses, (List[0], List[1]), Arch) + if self.IsToDatabase: + SqlCommand = """update %s set Value1 = '%s', Value2 = '%s', Value3 = '%s' + where ID = %s""" % (self.TblDec.Table, ConvertToSqlString2(List[0]), ConvertToSqlString2(List[1]), SUP_MODULE_LIST_STRING, Record[3]) + self.TblDec.Exec(SqlCommand) + + + for Key in LibraryClasses.keys(): + LibraryClass = LibraryClassClass() + LibraryClass.LibraryClass = Key[0] + LibraryClass.RecommendedInstance = NormPath(Key[1]) + LibraryClass.SupModuleList = SUP_MODULE_LIST + LibraryClass.SupArchList = LibraryClasses[Key] + self.Package.LibraryClassDeclarations.append(LibraryClass) + + ## GenPcds + # + # Gen Pcds of Dec + # .||| + # + # @param ContainerFile: The Dec file full path + # + def GenPcds(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_PCDS) + Pcds = {} + PcdToken = {} + # + # Get all Guids + # + RecordSet1 = self.RecordSet[MODEL_PCD_FIXED_AT_BUILD] + RecordSet2 = self.RecordSet[MODEL_PCD_PATCHABLE_IN_MODULE] + RecordSet3 = self.RecordSet[MODEL_PCD_FEATURE_FLAG] + RecordSet4 = self.RecordSet[MODEL_PCD_DYNAMIC_EX] + RecordSet5 = self.RecordSet[MODEL_PCD_DYNAMIC] + + # + # Go through each arch + # + for Arch in self.SupArchList: + for Record in RecordSet1: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: + (TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_FIXED_AT_BUILD, ContainerFile, Record[2]) + MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch) + PcdToken[Record[3]] = (TokenGuidCName, TokenName) + for Record in RecordSet2: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: + (TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_PATCHABLE_IN_MODULE, ContainerFile, Record[2]) + MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch) + PcdToken[Record[3]] = (TokenGuidCName, TokenName) + for Record in RecordSet3: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: + (TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_FEATURE_FLAG, ContainerFile, Record[2]) + MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch) + PcdToken[Record[3]] = (TokenGuidCName, TokenName) + for Record in RecordSet4: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: + (TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_DYNAMIC_EX, ContainerFile, Record[2]) + MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch) + PcdToken[Record[3]] = (TokenGuidCName, TokenName) + for Record in RecordSet5: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: + (TokenGuidCName, TokenName, Value, DatumType, Token, Type) = GetPcdOfDec(Record[0], TAB_PCDS_DYNAMIC, ContainerFile, Record[2]) + MergeArches(Pcds, (TokenGuidCName, TokenName, Value, DatumType, Token, Type), Arch) + PcdToken[Record[3]] = (TokenGuidCName, TokenName) + # + # Update to database + # + if self.IsToDatabase: + for Key in PcdToken.keys(): + SqlCommand = """update %s set Value2 = '%s' where ID = %s""" % (self.TblDec.Table, ".".join((PcdToken[Key][0], PcdToken[Key][1])), Key) + self.TblDec.Exec(SqlCommand) + + for Key in Pcds.keys(): + Pcd = PcdClass() + Pcd.CName = Key[1] + Pcd.Token = Key[4] + Pcd.TokenSpaceGuidCName = Key[0] + Pcd.DatumType = Key[3] + Pcd.DefaultValue = Key[2] + Pcd.ItemType = Key[5] + Pcd.SupArchList = Pcds[Key] + self.Package.PcdDeclarations.append(Pcd) + + ## Show detailed information of Package + # + # Print all members and their values of Package class + # + def ShowPackage(self): + M = self.Package + for Arch in M.Header.keys(): + print '\nArch =', Arch + print 'Filename =', M.Header[Arch].FileName + print 'FullPath =', M.Header[Arch].FullPath + print 'BaseName =', M.Header[Arch].Name + print 'Guid =', M.Header[Arch].Guid + print 'Version =', M.Header[Arch].Version + print 'DecSpecification =', M.Header[Arch].DecSpecification + print '\nIncludes =', M.Includes + for Item in M.Includes: + print Item.FilePath, Item.SupArchList + print '\nGuids =', M.GuidDeclarations + for Item in M.GuidDeclarations: + print Item.CName, Item.Guid, Item.SupArchList + print '\nProtocols =', M.ProtocolDeclarations + for Item in M.ProtocolDeclarations: + print Item.CName, Item.Guid, Item.SupArchList + print '\nPpis =', M.PpiDeclarations + for Item in M.PpiDeclarations: + print Item.CName, Item.Guid, Item.SupArchList + print '\nLibraryClasses =', M.LibraryClassDeclarations + for Item in M.LibraryClassDeclarations: + print Item.LibraryClass, Item.RecommendedInstance, Item.SupModuleList, Item.SupArchList + print '\nPcds =', M.PcdDeclarations + for Item in M.PcdDeclarations: + print 'CName=', Item.CName, 'TokenSpaceGuidCName=', Item.TokenSpaceGuidCName, 'DefaultValue=', Item.DefaultValue, 'ItemType=', Item.ItemType, 'Token=', Item.Token, 'DatumType=', Item.DatumType, Item.SupArchList + +## +# +# 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) + + W = os.getenv('WORKSPACE') + F = os.path.join(W, 'Nt32Pkg/Nt32Pkg.dec') + + Db = Database.Database('Dec.db') + Db.InitDatabase() + + P = Dec(os.path.normpath(F), True, True, W, Db) + P.ShowPackage() + + Db.Close() diff --git a/BaseTools/Source/Python/Common/DecClassObjectLight.py b/BaseTools/Source/Python/Common/DecClassObjectLight.py new file mode 100644 index 0000000000..7c572a56f0 --- /dev/null +++ b/BaseTools/Source/Python/Common/DecClassObjectLight.py @@ -0,0 +1,580 @@ +## @file +# This file is used to define each component of DEC file in light mode +# +# Copyright (c) 2008, 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 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 +from Misc import GetFiles +from String import * +from DataType import * +from CommonDataClass.PackageClass import * +from CommonDataClass import CommonClass +from BuildToolError import * +from Parsing import * + +# Global variable +Section = {TAB_UNKNOWN.upper() : MODEL_UNKNOWN, + TAB_DEC_DEFINES.upper() : MODEL_META_DATA_HEADER, + TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE, + TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS, + TAB_COMPONENTS.upper() : MODEL_META_DATA_COMPONENT, + TAB_GUIDS.upper() : MODEL_EFI_GUID, + TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL, + TAB_PPIS.upper() : MODEL_EFI_PPI, + TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : MODEL_PCD_FIXED_AT_BUILD, + TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : MODEL_PCD_PATCHABLE_IN_MODULE, + TAB_PCDS_FEATURE_FLAG_NULL.upper() : MODEL_PCD_FEATURE_FLAG, + TAB_PCDS_DYNAMIC_EX_NULL.upper() : MODEL_PCD_DYNAMIC_EX, + TAB_PCDS_DYNAMIC_NULL.upper() : MODEL_PCD_DYNAMIC, + TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION + } + +## DecObject +# +# This class defined basic Dec object which is used by inheriting +# +# @param object: Inherited from object class +# +class DecObject(object): + def __init__(self): + object.__init__() + +## Dec +# +# This class defined the structure used in Dec object +# +# @param DecObject: Inherited from DecObject class +# @param Filename: Input value for Filename of Dec file, default is None +# @param IsMergeAllArches: Input value for IsMergeAllArches +# True is to merge all arches +# Fales is not to merge all arches +# default is False +# @param IsToPackage: Input value for IsToPackage +# True is to transfer to PackageObject automatically +# False is not to transfer to PackageObject automatically +# default is False +# @param WorkspaceDir: Input value for current workspace directory, default is None +# +# @var Identification: To store value for Identification, it is a structure as Identification +# @var Defines: To store value for Defines, it is a structure as DecDefines +# @var UserExtensions: To store value for UserExtensions +# @var Package: To store value for Package, it is a structure as PackageClass +# @var WorkspaceDir: To store value for WorkspaceDir +# @var Contents: To store value for Contents, it is a structure as DecContents +# @var KeyList: To store value for KeyList, a list for all Keys used in Dec +# +class Dec(DecObject): + def __init__(self, Filename = None, IsToPackage = False, WorkspaceDir = None, AllGuidVersionDict = None, SupArchList = DataType.ARCH_LIST): + self.Identification = IdentificationClass() + self.Package = PackageClass() + self.UserExtensions = '' + self.WorkspaceDir = WorkspaceDir + self.SupArchList = SupArchList + self.AllGuidVersionDict = {} + if AllGuidVersionDict: + self.AllGuidVersionDict = AllGuidVersionDict + + self.KeyList = [ + TAB_INCLUDES, TAB_GUIDS, TAB_PROTOCOLS, TAB_PPIS, TAB_LIBRARY_CLASSES, \ + TAB_PCDS_FIXED_AT_BUILD_NULL, TAB_PCDS_PATCHABLE_IN_MODULE_NULL, TAB_PCDS_FEATURE_FLAG_NULL, \ + TAB_PCDS_DYNAMIC_NULL, TAB_PCDS_DYNAMIC_EX_NULL, TAB_DEC_DEFINES + ] + # Upper all KEYs to ignore case sensitive when parsing + self.KeyList = map(lambda c: c.upper(), self.KeyList) + + # Init RecordSet + self.RecordSet = {} + for Key in self.KeyList: + self.RecordSet[Section[Key]] = [] + + # Init Comment + self.SectionHeaderCommentDict = {} + + # Load Dec file if filename is not None + if Filename != None: + self.LoadDecFile(Filename) + + # Transfer to Package Object if IsToPackage is True + if IsToPackage: + self.DecToPackage() + + ## Load Dec file + # + # Load the file if it exists + # + # @param Filename: Input value for filename of Dec file + # + def LoadDecFile(self, Filename): + # Insert a record for file + Filename = NormPath(Filename) + self.Identification.FullPath = Filename + (self.Identification.RelaPath, self.Identification.FileName) = os.path.split(Filename) + if self.Identification.FullPath.find(self.WorkspaceDir) > -1: + self.Identification.PackagePath = os.path.dirname(self.Identification.FullPath[len(self.WorkspaceDir) + 1:]) + + # Init common datas + IfDefList, SectionItemList, CurrentSection, ArchList, ThirdList, IncludeFiles = \ + [], [], TAB_UNKNOWN, [], [], [] + LineNo = 0 + + # Parse file content + IsFindBlockComment = False + ReservedLine = '' + Comment = '' + for Line in open(Filename, 'r'): + LineNo = LineNo + 1 + # Remove comment block + if Line.find(TAB_COMMENT_R8_START) > -1: + ReservedLine = GetSplitValueList(Line, TAB_COMMENT_R8_START, 1)[0] + if ReservedLine.strip().startswith(TAB_COMMENT_SPLIT): + Comment = Comment + Line.strip() + '\n' + ReservedLine = '' + else: + Comment = Comment + Line[len(ReservedLine):] + '\n' + IsFindBlockComment = True + if not ReservedLine: + continue + if Line.find(TAB_COMMENT_R8_END) > -1: + Comment = Comment + Line[:Line.find(TAB_COMMENT_R8_END) + len(TAB_COMMENT_R8_END)] + '\n' + Line = ReservedLine + GetSplitValueList(Line, TAB_COMMENT_R8_END, 1)[1] + ReservedLine = '' + IsFindBlockComment = False + if IsFindBlockComment: + Comment = Comment + Line.strip() + '\n' + continue + + # Remove comments at tail and remove spaces again + if Line.strip().startswith(TAB_COMMENT_SPLIT) or Line.strip().startswith('--/'): + Comment = Comment + Line.strip() + '\n' + Line = CleanString(Line) + if Line == '': + continue + + ## Find a new section tab + # First insert previous section items + # And then parse the content of the new section + # + if Line.startswith(TAB_SECTION_START) and Line.endswith(TAB_SECTION_END): + # Insert items data of previous section + Model = Section[CurrentSection.upper()] + InsertSectionItems(Model, CurrentSection, SectionItemList, ArchList, ThirdList, self.RecordSet) + # Parse the new section + SectionItemList = [] + ArchList = [] + ThirdList = [] + + CurrentSection = '' + LineList = GetSplitValueList(Line[len(TAB_SECTION_START):len(Line) - len(TAB_SECTION_END)], TAB_COMMA_SPLIT) + for Item in LineList: + ItemList = GetSplitValueList(Item, TAB_SPLIT) + if CurrentSection == '': + CurrentSection = ItemList[0] + else: + if CurrentSection != ItemList[0]: + EdkLogger.error("Parser", PARSER_ERROR, "Different section names '%s' and '%s' are found in one section definition, this is not allowed." % (CurrentSection, ItemList[0]), File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError) + if CurrentSection.upper() not in self.KeyList: + RaiseParserError(Line, CurrentSection, Filename, '', LineNo) + ItemList.append('') + ItemList.append('') + if len(ItemList) > 5: + RaiseParserError(Line, CurrentSection, Filename, '', LineNo) + else: + if ItemList[1] != '' and ItemList[1].upper() not in ARCH_LIST_FULL: + EdkLogger.error("Parser", PARSER_ERROR, "Invalid Arch definition '%s' found" % ItemList[1], File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError) + ArchList.append(ItemList[1].upper()) + ThirdList.append(ItemList[2]) + + if Comment: + if Comment.endswith('\n'): + Comment = Comment[:len(Comment) - len('\n')] + self.SectionHeaderCommentDict[Section[CurrentSection.upper()]] = Comment + Comment = '' + continue + + # Not in any defined section + if CurrentSection == TAB_UNKNOWN: + ErrorMsg = "%s is not in any defined section" % Line + EdkLogger.error("Parser", PARSER_ERROR, ErrorMsg, File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError) + + # Add a section item + SectionItemList.append([Line, LineNo, Comment]) + Comment = '' + # End of parse + #End of For + + # + # Insert items data of last section + # + Model = Section[CurrentSection.upper()] + InsertSectionItems(Model, CurrentSection, SectionItemList, ArchList, ThirdList, self.RecordSet) + if Comment != '': + self.SectionHeaderCommentDict[Model] = Comment + Comment = '' + + ## Package Object to DEC file + def PackageToDec(self, Package): + Dec = '' + DecList = sdict() + SectionHeaderCommentDict = {} + if Package == None: + return Dec + + PackageHeader = Package.PackageHeader + TmpList = [] + if PackageHeader.Name: + TmpList.append(TAB_DEC_DEFINES_PACKAGE_NAME + ' = ' + PackageHeader.Name) + if PackageHeader.Guid: + TmpList.append(TAB_DEC_DEFINES_PACKAGE_GUID + ' = ' + PackageHeader.Guid) + if PackageHeader.Version: + TmpList.append(TAB_DEC_DEFINES_PACKAGE_VERSION + ' = ' + PackageHeader.Version) + if PackageHeader.DecSpecification: + TmpList.append(TAB_DEC_DEFINES_DEC_SPECIFICATION + ' = ' + PackageHeader.DecSpecification) + if Package.UserExtensions != None: + for Item in Package.UserExtensions.Defines: + TmpList.append(Item) + DecList['Defines'] =TmpList + if PackageHeader.Description != '': + SectionHeaderCommentDict['Defines'] = PackageHeader.Description + + for Item in Package.Includes: + Key = 'Includes.' + Item.SupArchList + Value = Item.FilePath + GenMetaDatSectionItem(Key, Value, DecList) + + for Item in Package.GuidDeclarations: + Key = 'Guids.' + Item.SupArchList + Value = Item.CName + '=' + Item.Guid + GenMetaDatSectionItem(Key, Value, DecList) + + for Item in Package.ProtocolDeclarations: + Key = 'Protocols.' + Item.SupArchList + Value = Item.CName + '=' + Item.Guid + GenMetaDatSectionItem(Key, Value, DecList) + + for Item in Package.PpiDeclarations: + Key = 'Ppis.' + Item.SupArchList + Value = Item.CName + '=' + Item.Guid + GenMetaDatSectionItem(Key, Value, DecList) + + for Item in Package.LibraryClassDeclarations: + Key = 'LibraryClasses.' + Item.SupArchList + Value = Item.LibraryClass + '|' + Item.RecommendedInstance + GenMetaDatSectionItem(Key, Value, DecList) + + for Item in Package.PcdDeclarations: + Key = 'Pcds' + Item.ItemType + '.' + Item.SupArchList + Value = Item.TokenSpaceGuidCName + '.' + Item.CName + if Item.DefaultValue != '': + Value = Value + '|' + Item.DefaultValue + if Item.DatumType != '': + Value = Value + '|' + Item.DatumType + if Item.Token != '': + Value = Value + '|' + Item.Token + GenMetaDatSectionItem(Key, Value, DecList) + + # Transfer Package to Inf + for Key in DecList: + if Key in SectionHeaderCommentDict: + List = SectionHeaderCommentDict[Key].split('\r') + for Item in List: + Dec = Dec + Item + '\n' + Dec = Dec + '[' + Key + ']' + '\n' + for Value in DecList[Key]: + if type(Value) == type([]): + for SubValue in Value: + Dec = Dec + ' ' + SubValue + '\n' + else: + Dec = Dec + ' ' + Value + '\n' + Dec = Dec + '\n' + + return Dec + + ## Transfer to Package Object + # + # Transfer all contents of a Dec file to a standard Package Object + # + def DecToPackage(self): + # Init global information for the file + ContainerFile = self.Identification.FullPath + + # Generate Package Header + self.GenPackageHeader(ContainerFile) + + # Generate Includes + # Only for R8 + self.GenIncludes(ContainerFile) + + # Generate Guids + self.GenGuidProtocolPpis(DataType.TAB_GUIDS, ContainerFile) + + # Generate Protocols + self.GenGuidProtocolPpis(DataType.TAB_PROTOCOLS, ContainerFile) + + # Generate Ppis + self.GenGuidProtocolPpis(DataType.TAB_PPIS, ContainerFile) + + # Generate LibraryClasses + self.GenLibraryClasses(ContainerFile) + + # Generate Pcds + self.GenPcds(ContainerFile) + + # Init MiscFiles + self.GenMiscFiles(ContainerFile) + + ## GenMiscFiles + # + def GenMiscFiles(self, ContainerFile): + MiscFiles = MiscFileClass() + MiscFiles.Name = 'ModuleFiles' + for Item in GetFiles(os.path.dirname(ContainerFile), ['CVS', '.svn'], False): + File = CommonClass.FileClass() + File.Filename = Item + MiscFiles.Files.append(File) + self.Package.MiscFiles = MiscFiles + + ## Get Package Header + # + # Gen Package Header of Dec as = + # + # @param ContainerFile: The Dec file full path + # + def GenPackageHeader(self, ContainerFile): + EdkLogger.debug(2, "Generate PackageHeader ...") + # + # Update all defines item in database + # + RecordSet = self.RecordSet[MODEL_META_DATA_HEADER] + PackageHeader = PackageHeaderClass() + OtherDefines = [] + for Record in RecordSet: + ValueList = GetSplitValueList(Record[0], TAB_EQUAL_SPLIT) + if len(ValueList) != 2: + OtherDefines.append(Record[0]) + else: + Name = ValueList[0] + Value = ValueList[1] + if Name == TAB_DEC_DEFINES_PACKAGE_NAME: + PackageHeader.Name = Value + elif Name == TAB_DEC_DEFINES_PACKAGE_GUID: + PackageHeader.Guid = Value + elif Name == TAB_DEC_DEFINES_PACKAGE_VERSION: + PackageHeader.Version = Value + elif Name == TAB_DEC_DEFINES_DEC_SPECIFICATION: + PackageHeader.DecSpecification = Value + else: + OtherDefines.append(Record[0]) + + PackageHeader.FileName = self.Identification.FileName + PackageHeader.FullPath = self.Identification.FullPath + PackageHeader.RelaPath = self.Identification.RelaPath + PackageHeader.PackagePath = self.Identification.PackagePath + PackageHeader.ModulePath = self.Identification.ModulePath + PackageHeader.CombinePath = os.path.normpath(os.path.join(PackageHeader.PackagePath, PackageHeader.ModulePath, PackageHeader.FileName)) + + if MODEL_META_DATA_HEADER in self.SectionHeaderCommentDict: + PackageHeader.Description = self.SectionHeaderCommentDict[MODEL_META_DATA_HEADER] + + self.Package.PackageHeader = PackageHeader + UE = UserExtensionsClass() + UE.Defines = OtherDefines + self.Package.UserExtensions = UE + + + ## GenIncludes + # + # Gen Includes of Dec + # + # @param ContainerFile: The Dec file full path + # + def GenIncludes(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_INCLUDES) + Includes = {} + # Get all Includes + RecordSet = self.RecordSet[MODEL_EFI_INCLUDE] + + # Go through each arch + for Record in RecordSet: + Arch = Record[1] + Key = Record[0] + Include = IncludeClass() + Include.FilePath = NormPath(Key) + Include.SupArchList = Arch + self.Package.Includes.append(Include) + + ## GenPpis + # + # Gen Ppis of Dec + # = + # + # @param ContainerFile: The Dec file full path + # + def GenGuidProtocolPpis(self, Type, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % Type) + Lists = {} + # Get all Items + RecordSet = self.RecordSet[Section[Type.upper()]] + + # Go through each arch + for Record in RecordSet: + Arch = Record[1] + (Name, Value) = GetGuidsProtocolsPpisOfDec(Record[0], Type, ContainerFile, Record[2]) + + ListMember = None + if Type == TAB_GUIDS: + ListMember = self.Package.GuidDeclarations + elif Type == TAB_PROTOCOLS: + ListMember = self.Package.ProtocolDeclarations + elif Type == TAB_PPIS: + ListMember = self.Package.PpiDeclarations + + ListClass = GuidProtocolPpiCommonClass() + ListClass.CName = Name + ListClass.Guid = Value + ListClass.SupArchList = Arch + ListMember.append(ListClass) + + ## GenLibraryClasses + # + # Gen LibraryClasses of Dec + # = + # + # @param ContainerFile: The Dec file full path + # + def GenLibraryClasses(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_LIBRARY_CLASSES) + LibraryClasses = {} + # Get all Guids + RecordSet = self.RecordSet[MODEL_EFI_LIBRARY_CLASS] + + # Go through each arch + for Record in RecordSet: + Arch = Record[1] + List = GetSplitValueList(Record[0], DataType.TAB_VALUE_SPLIT) + if len(List) != 2: + continue + LibraryClass = LibraryClassClass() + LibraryClass.LibraryClass = List[0] + LibraryClass.RecommendedInstance = NormPath(List[1]) + LibraryClass.SupArchList = Arch + self.Package.LibraryClassDeclarations.append(LibraryClass) + + def AddPcd(self, CName, Token, TokenSpaceGuidCName, DatumType, DefaultValue, ItemType, Arch): + Pcd = CommonClass.PcdClass() + Pcd.CName = CName + Pcd.Token = Token + Pcd.TokenSpaceGuidCName = TokenSpaceGuidCName + Pcd.DatumType = DatumType + Pcd.DefaultValue = DefaultValue + Pcd.ItemType = ItemType + Pcd.SupArchList = Arch + self.Package.PcdDeclarations.append(Pcd) + + ## GenPcds + # + # Gen Pcds of Dec + # .||| + # + # @param ContainerFile: The Dec file full path + # + def GenPcds(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_PCDS) + Pcds = {} + PcdToken = {} + # Get all Pcds + RecordSet1 = self.RecordSet[MODEL_PCD_FIXED_AT_BUILD] + RecordSet2 = self.RecordSet[MODEL_PCD_PATCHABLE_IN_MODULE] + RecordSet3 = self.RecordSet[MODEL_PCD_FEATURE_FLAG] + RecordSet4 = self.RecordSet[MODEL_PCD_DYNAMIC_EX] + RecordSet5 = self.RecordSet[MODEL_PCD_DYNAMIC] + + # Go through each pcd + for Record in RecordSet1: + Arch = Record[1] + (TokenGuidCName, TokenName, DefaultValue, DatumType, Token, ItemType) = GetPcdOfDec(Record[0], TAB_PCDS_FIXED_AT_BUILD, ContainerFile, Record[2]) + self.AddPcd(TokenName, Token, TokenGuidCName, DatumType, DefaultValue, ItemType, Arch) + for Record in RecordSet2: + Arch = Record[1] + (TokenGuidCName, TokenName, DefaultValue, DatumType, Token, ItemType) = GetPcdOfDec(Record[0], TAB_PCDS_PATCHABLE_IN_MODULE, ContainerFile, Record[2]) + self.AddPcd(TokenName, Token, TokenGuidCName, DatumType, DefaultValue, ItemType, Arch) + for Record in RecordSet3: + Arch = Record[1] + (TokenGuidCName, TokenName, DefaultValue, DatumType, Token, ItemType) = GetPcdOfDec(Record[0], TAB_PCDS_FEATURE_FLAG, ContainerFile, Record[2]) + self.AddPcd(TokenName, Token, TokenGuidCName, DatumType, DefaultValue, ItemType, Arch) + for Record in RecordSet4: + Arch = Record[1] + (TokenGuidCName, TokenName, DefaultValue, DatumType, Token, ItemType) = GetPcdOfDec(Record[0], TAB_PCDS_DYNAMIC_EX, ContainerFile, Record[2]) + self.AddPcd(TokenName, Token, TokenGuidCName, DatumType, DefaultValue, ItemType, Arch) + for Record in RecordSet5: + Arch = Record[1] + (TokenGuidCName, TokenName, DefaultValue, DatumType, Token, ItemType) = GetPcdOfDec(Record[0], TAB_PCDS_DYNAMIC, ContainerFile, Record[2]) + self.AddPcd(TokenName, Token, TokenGuidCName, DatumType, DefaultValue, ItemType, Arch) + + ## Show detailed information of Package + # + # Print all members and their values of Package class + # + def ShowPackage(self): + M = self.Package + print 'Filename =', M.PackageHeader.FileName + print 'FullPath =', M.PackageHeader.FullPath + print 'RelaPath =', M.PackageHeader.RelaPath + print 'PackagePath =', M.PackageHeader.PackagePath + print 'ModulePath =', M.PackageHeader.ModulePath + print 'CombinePath =', M.PackageHeader.CombinePath + + print 'BaseName =', M.PackageHeader.Name + print 'Guid =', M.PackageHeader.Guid + print 'Version =', M.PackageHeader.Version + print 'DecSpecification =', M.PackageHeader.DecSpecification + + print '\nIncludes ='#, M.Includes + for Item in M.Includes: + print Item.FilePath, Item.SupArchList + print '\nGuids ='#, M.GuidDeclarations + for Item in M.GuidDeclarations: + print Item.CName, Item.Guid, Item.SupArchList + print '\nProtocols ='#, M.ProtocolDeclarations + for Item in M.ProtocolDeclarations: + print Item.CName, Item.Guid, Item.SupArchList + print '\nPpis ='#, M.PpiDeclarations + for Item in M.PpiDeclarations: + print Item.CName, Item.Guid, Item.SupArchList + print '\nLibraryClasses ='#, M.LibraryClassDeclarations + for Item in M.LibraryClassDeclarations: + print Item.LibraryClass, Item.RecommendedInstance, Item.SupModuleList, Item.SupArchList + print '\nPcds ='#, M.PcdDeclarations + for Item in M.PcdDeclarations: + print 'CName=', Item.CName, 'TokenSpaceGuidCName=', Item.TokenSpaceGuidCName, 'DefaultValue=', Item.DefaultValue, 'ItemType=', Item.ItemType, 'Token=', Item.Token, 'DatumType=', Item.DatumType, Item.SupArchList + print '\nUserExtensions =', M.UserExtensions.Defines + print '\n*** FileList ***' + for Item in M.MiscFiles.Files: + print Item.Filename + print '****************\n' + +## +# +# 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.QUIET) + + W = os.getenv('WORKSPACE') + F = os.path.join(W, 'MdeModulePkg/MdeModulePkg.dec') + + P = Dec(os.path.normpath(F), True, W) + P.ShowPackage() + print P.PackageToDec(P.Package) diff --git a/BaseTools/Source/Python/Common/Dictionary.py b/BaseTools/Source/Python/Common/Dictionary.py new file mode 100644 index 0000000000..3c968f5ec6 --- /dev/null +++ b/BaseTools/Source/Python/Common/Dictionary.py @@ -0,0 +1,75 @@ +## @file +# Define a dictionary structure +# +# Copyright (c) 2007, 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 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 EdkLogger +from DataType import * + +## Convert a text file to a dictionary +# +# Convert a text file to a dictionary of (name:value) pairs. +# +# @retval 0 Convert successful +# @retval 1 Open file failed +# +def ConvertTextFileToDictionary(FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter): + try: + F = open(FileName,'r') + Keys = [] + for Line in F: + if Line.startswith(CommentCharacter): + continue + LineList = Line.split(KeySplitCharacter,1) + if len(LineList) >= 2: + Key = LineList[0].split() + if len(Key) == 1 and Key[0][0] != CommentCharacter and Key[0] not in Keys: + if ValueSplitFlag: + Dictionary[Key[0]] = LineList[1].replace('\\','/').split(ValueSplitCharacter) + else: + Dictionary[Key[0]] = LineList[1].strip().replace('\\','/') + Keys += [Key[0]] + F.close() + return 0 + except: + EdkLogger.info('Open file failed') + return 1 + +## Print the dictionary +# +# Print all items of dictionary one by one +# +# @param Dict: The dictionary to be printed +# +def printDict(Dict): + if Dict != None: + KeyList = Dict.keys() + for Key in KeyList: + if Dict[Key] != '': + print Key + ' = ' + str(Dict[Key]) + +## Print the dictionary +# +# Print the items of dictionary which matched with input key +# +# @param list: The dictionary to be printed +# @param key: The key of the item to be printed +# +def printList(Key, List): + if type(List) == type([]): + if len(List) > 0: + if key.find(TAB_SPLIT) != -1: + print "\n" + Key + for Item in List: + print Item diff --git a/BaseTools/Source/Python/Common/DscClassObject.py b/BaseTools/Source/Python/Common/DscClassObject.py new file mode 100644 index 0000000000..ddccf6507d --- /dev/null +++ b/BaseTools/Source/Python/Common/DscClassObject.py @@ -0,0 +1,1434 @@ +## @file +# This file is used to define each component of DSC file +# +# Copyright (c) 2007 ~ 2008, 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 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 EdkLogger as EdkLogger +import Database +from String import * +from Parsing import * +from DataType import * +from Identification import * +from Dictionary import * +from CommonDataClass.PlatformClass import * +from CommonDataClass.CommonClass import SkuInfoClass +from BuildToolError import * +from Misc import sdict +import GlobalData +from Table.TableDsc import TableDsc + +# +# Global variable +# +Section = {TAB_UNKNOWN.upper() : MODEL_UNKNOWN, + TAB_DSC_DEFINES.upper() : MODEL_META_DATA_HEADER, + TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION, + TAB_SKUIDS.upper() : MODEL_EFI_SKU_ID, + TAB_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE, + TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS, + TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : MODEL_PCD_FIXED_AT_BUILD, + TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : MODEL_PCD_PATCHABLE_IN_MODULE, + TAB_PCDS_FEATURE_FLAG_NULL.upper() : MODEL_PCD_FEATURE_FLAG, + TAB_PCDS_DYNAMIC_EX_NULL.upper() : MODEL_PCD_DYNAMIC_EX, + TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT, + TAB_PCDS_DYNAMIC_EX_VPD_NULL.upper() : MODEL_PCD_DYNAMIC_EX_VPD, + TAB_PCDS_DYNAMIC_EX_HII_NULL.upper() : MODEL_PCD_DYNAMIC_EX_HII, + TAB_PCDS_DYNAMIC_NULL.upper() : MODEL_PCD_DYNAMIC, + TAB_PCDS_DYNAMIC_DEFAULT_NULL.upper() : MODEL_PCD_DYNAMIC_DEFAULT, + TAB_PCDS_DYNAMIC_VPD_NULL.upper() : MODEL_PCD_DYNAMIC_VPD, + TAB_PCDS_DYNAMIC_HII_NULL.upper() : MODEL_PCD_DYNAMIC_HII, + TAB_COMPONENTS.upper() : MODEL_META_DATA_COMPONENT, + TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION + } + +## DscObject +# +# This class defined basic Dsc object which is used by inheriting +# +# @param object: Inherited from object class +# +class DscObject(object): + def __init__(self): + object.__init__() + +## Dsc +# +# This class defined the structure used in Dsc object +# +# @param DscObject: Inherited from InfObject class +# @param Ffilename: Input value for Ffilename of Inf file, default is None +# @param IsMergeAllArches: Input value for IsMergeAllArches +# True is to merge all arches +# Fales is not to merge all arches +# default is False +# @param IsToPlatform: Input value for IsToPlatform +# True is to transfer to ModuleObject automatically +# False is not to transfer to ModuleObject automatically +# default is False +# @param WorkspaceDir: Input value for current workspace directory, default is None +# +# @var _NullClassIndex: To store value for _NullClassIndex, default is 0 +# @var Identification: To store value for Identification, it is a structure as Identification +# @var Defines: To store value for Defines, it is a structure as DscDefines +# @var Contents: To store value for Contents, it is a structure as DscContents +# @var UserExtensions: To store value for UserExtensions +# @var Platform: To store value for Platform, it is a structure as PlatformClass +# @var WorkspaceDir: To store value for WorkspaceDir +# @var KeyList: To store value for KeyList, a list for all Keys used in Dec +# +class Dsc(DscObject): + _NullClassIndex = 0 + + def __init__(self, Filename = None, IsToDatabase = False, IsToPlatform = False, WorkspaceDir = None, Database = None): + self.Identification = Identification() + self.Platform = PlatformClass() + self.UserExtensions = '' + self.WorkspaceDir = WorkspaceDir + self.IsToDatabase = IsToDatabase + + self.Cur = Database.Cur + self.TblFile = Database.TblFile + self.TblDsc = Database.TblDsc + + + self.KeyList = [ + TAB_SKUIDS, TAB_LIBRARIES, TAB_LIBRARY_CLASSES, TAB_BUILD_OPTIONS, TAB_PCDS_FIXED_AT_BUILD_NULL, \ + TAB_PCDS_PATCHABLE_IN_MODULE_NULL, TAB_PCDS_FEATURE_FLAG_NULL, \ + TAB_PCDS_DYNAMIC_DEFAULT_NULL, TAB_PCDS_DYNAMIC_HII_NULL, TAB_PCDS_DYNAMIC_VPD_NULL, \ + TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL, TAB_PCDS_DYNAMIC_EX_HII_NULL, TAB_PCDS_DYNAMIC_EX_VPD_NULL, \ + TAB_COMPONENTS, TAB_DSC_DEFINES + ] + + self.PcdToken = {} + + # + # Upper all KEYs to ignore case sensitive when parsing + # + self.KeyList = map(lambda c: c.upper(), self.KeyList) + + # + # Init RecordSet + # +# self.RecordSet = {} +# for Key in self.KeyList: +# self.RecordSet[Section[Key]] = [] + + # + # Load Dsc file if filename is not None + # + if Filename != None: + self.LoadDscFile(Filename) + + # + # Transfer to Platform Object if IsToPlatform is True + # + if IsToPlatform: + self.DscToPlatform() + + ## Transfer to Platform Object + # + # Transfer all contents of an Inf file to a standard Module Object + # + def DscToPlatform(self): + # + # Init global information for the file + # + ContainerFile = self.Identification.FileFullPath + + # + # Generate Platform Header + # + self.GenPlatformHeader(ContainerFile) + + # + # Generate BuildOptions + # + self.GenBuildOptions(ContainerFile) + + # + # Generate SkuInfos + # + self.GenSkuInfos(ContainerFile) + + # + # Generate Libraries + # + self.GenLibraries(ContainerFile) + + # + # Generate LibraryClasses + # + self.GenLibraryClasses(ContainerFile) + + # + # Generate Pcds + # + self.GenPcds(DataType.TAB_PCDS_FIXED_AT_BUILD, ContainerFile) + self.GenPcds(DataType.TAB_PCDS_PATCHABLE_IN_MODULE, ContainerFile) + self.GenFeatureFlagPcds(DataType.TAB_PCDS_FEATURE_FLAG, ContainerFile) + self.GenDynamicDefaultPcds(DataType.TAB_PCDS_DYNAMIC_DEFAULT, ContainerFile) + self.GenDynamicDefaultPcds(DataType.TAB_PCDS_DYNAMIC_EX_DEFAULT, ContainerFile) + self.GenDynamicHiiPcds(DataType.TAB_PCDS_DYNAMIC_HII, ContainerFile) + self.GenDynamicHiiPcds(DataType.TAB_PCDS_DYNAMIC_EX_HII, ContainerFile) + self.GenDynamicVpdPcds(DataType.TAB_PCDS_DYNAMIC_VPD, ContainerFile) + self.GenDynamicVpdPcds(DataType.TAB_PCDS_DYNAMIC_EX_VPD, ContainerFile) + + # + # Generate Components + # + self.GenComponents(ContainerFile) + + # + # Update to database + # + if self.IsToDatabase: + for Key in self.PcdToken.keys(): + SqlCommand = """update %s set Value2 = '%s' where ID = %s""" % (self.TblDsc.Table, ".".join((self.PcdToken[Key][0], self.PcdToken[Key][1])), Key) + self.TblDsc.Exec(SqlCommand) + #End of DscToPlatform + + ## Get Platform Header + # + # Gen Platform Header of Dsc as = + # + # @param ContainerFile: The Dsc file full path + # + def GenPlatformHeader(self, ContainerFile): + EdkLogger.debug(2, "Generate PlatformHeader ...") + # + # Update all defines item in database + # + SqlCommand = """select ID, Value1, Arch, StartLine from %s + where Model = %s + and BelongsToFile = %s + and Enabled > -1""" % (self.TblDsc.Table, MODEL_META_DATA_HEADER, self.FileID) + RecordSet = self.TblDsc.Exec(SqlCommand) + for Record in RecordSet: + ValueList = GetSplitValueList(Record[1], TAB_EQUAL_SPLIT) + if len(ValueList) != 2: + RaiseParserError(Record[1], 'Defines', ContainerFile, ' = ', Record[3]) + ID, Value1, Value2, Arch = Record[0], ValueList[0], ValueList[1], Record[2] + SqlCommand = """update %s set Value1 = '%s', Value2 = '%s' + where ID = %s""" % (self.TblDsc.Table, ConvertToSqlString2(Value1), ConvertToSqlString2(Value2), ID) + self.TblDsc.Exec(SqlCommand) + + # + # Get detailed information + # + for Arch in DataType.ARCH_LIST: + PlatformHeader = PlatformHeaderClass() + + PlatformHeader.Name = QueryDefinesItem(self.TblDsc, TAB_DSC_DEFINES_PLATFORM_NAME, Arch, self.FileID)[0] + PlatformHeader.Guid = QueryDefinesItem(self.TblDsc, TAB_DSC_DEFINES_PLATFORM_GUID, Arch, self.FileID)[0] + PlatformHeader.Version = QueryDefinesItem(self.TblDsc, TAB_DSC_DEFINES_PLATFORM_VERSION, Arch, self.FileID)[0] + PlatformHeader.FileName = self.Identification.FileName + PlatformHeader.FullPath = self.Identification.FileFullPath + PlatformHeader.DscSpecification = QueryDefinesItem(self.TblDsc, TAB_DSC_DEFINES_DSC_SPECIFICATION, Arch, self.FileID)[0] + + PlatformHeader.SkuIdName = QueryDefinesItem(self.TblDsc, TAB_DSC_DEFINES_SKUID_IDENTIFIER, Arch, self.FileID) + PlatformHeader.SupArchList = QueryDefinesItem(self.TblDsc, TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES, Arch, self.FileID) + PlatformHeader.BuildTargets = QueryDefinesItem(self.TblDsc, TAB_DSC_DEFINES_BUILD_TARGETS, Arch, self.FileID) + PlatformHeader.OutputDirectory = NormPath(QueryDefinesItem(self.TblDsc, TAB_DSC_DEFINES_OUTPUT_DIRECTORY, Arch, self.FileID)[0]) + PlatformHeader.BuildNumber = QueryDefinesItem(self.TblDsc, TAB_DSC_DEFINES_BUILD_NUMBER, Arch, self.FileID)[0] + PlatformHeader.MakefileName = QueryDefinesItem(self.TblDsc, TAB_DSC_DEFINES_MAKEFILE_NAME, Arch, self.FileID)[0] + + PlatformHeader.BsBaseAddress = QueryDefinesItem(self.TblDsc, TAB_DSC_DEFINES_BS_BASE_ADDRESS, Arch, self.FileID)[0] + PlatformHeader.RtBaseAddress = QueryDefinesItem(self.TblDsc, TAB_DSC_DEFINES_RT_BASE_ADDRESS, Arch, self.FileID)[0] + + self.Platform.Header[Arch] = PlatformHeader + Fdf = PlatformFlashDefinitionFileClass() + Fdf.FilePath = NormPath(QueryDefinesItem(self.TblDsc, TAB_DSC_DEFINES_FLASH_DEFINITION, Arch, self.FileID)[0]) + self.Platform.FlashDefinitionFile = Fdf + + ## GenBuildOptions + # + # Gen BuildOptions of Dsc + # [:]=Flag + # + # @param ContainerFile: The Dsc file full path + # + def GenBuildOptions(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_BUILD_OPTIONS) + BuildOptions = {} + # + # Get all include files + # + IncludeFiles = QueryDscItem(self.TblDsc, MODEL_META_DATA_INCLUDE, MODEL_META_DATA_BUILD_OPTION, self.FileID) + + # + # Get all BuildOptions + # + RecordSet = QueryDscItem(self.TblDsc, MODEL_META_DATA_BUILD_OPTION, -1, self.FileID) + + # + # Go through each arch + # + for Arch in DataType.ARCH_LIST: + for IncludeFile in IncludeFiles: + if IncludeFile[1] == Arch or IncludeFile[1] == TAB_ARCH_COMMON.upper(): + Filename = CheckFileExist(self.WorkspaceDir, IncludeFile[0], ContainerFile, TAB_BUILD_OPTIONS, '', IncludeFile[2]) + for NewItem in open(Filename, 'r').readlines(): + if CleanString(NewItem) == '': + continue + (Family, ToolChain, Flag) = GetBuildOption(NewItem, Filename, -1) + MergeArches(BuildOptions, (Family, ToolChain, Flag), Arch) + + for Record in RecordSet: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON.upper(): + (Family, ToolChain, Flag) = GetBuildOption(Record[0], ContainerFile, Record[2]) + MergeArches(BuildOptions, (Family, ToolChain, Flag), Arch) + # + # Update to Database + # + if self.IsToDatabase: + SqlCommand = """update %s set Value1 = '%s', Value2 = '%s', Value3 = '%s' + where ID = %s""" % (self.TblDsc.Table, ConvertToSqlString2(Family), ConvertToSqlString2(ToolChain), ConvertToSqlString2(Flag), Record[3]) + self.TblDsc.Exec(SqlCommand) + + for Key in BuildOptions.keys(): + BuildOption = BuildOptionClass(Key[0], Key[1], Key[2]) + BuildOption.SupArchList = BuildOptions[Key] + self.Platform.BuildOptions.BuildOptionList.append(BuildOption) + + ## GenSkuInfos + # + # Gen SkuInfos of Dsc + # | + # + # @param ContainerFile: The Dsc file full path + # + def GenSkuInfos(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_SKUIDS) + # + # SkuIds + # | + # + self.Platform.SkuInfos.SkuInfoList['DEFAULT'] = '0' + + # + # Get all include files + # + IncludeFiles = QueryDscItem(self.TblDsc, MODEL_META_DATA_INCLUDE, MODEL_EFI_SKU_ID, self.FileID) + + # + # Get all SkuInfos + # + RecordSet = QueryDscItem(self.TblDsc, MODEL_EFI_SKU_ID, -1, self.FileID) + + # + # Go through each arch + # + for Arch in DataType.ARCH_LIST: + for IncludeFile in IncludeFiles: + if IncludeFile[1] == Arch or IncludeFile[1] == TAB_ARCH_COMMON.upper(): + Filename = CheckFileExist(self.WorkspaceDir, IncludeFile[0], ContainerFile, TAB_SKUIDS, '', IncludeFile[2]) + for NewItem in open(Filename, 'r').readlines(): + if CleanString(NewItem) == '': + continue + List = GetSplitValueList(NewItem) + if len(List) != 2: + RaiseParserError(NewItem, TAB_SKUIDS, Filename, '|') + else: + self.Platform.SkuInfos.SkuInfoList[List[1]] = List[0] + + for Record in RecordSet: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON.upper(): + List = GetSplitValueList(Record[0]) + if len(List) != 2: + RaiseParserError(Record[0], TAB_SKUIDS, ContainerFile, '|') + else: + self.Platform.SkuInfos.SkuInfoList[List[1]] = List[0] + # + # Update to Database + # + if self.IsToDatabase: + SqlCommand = """update %s set Value1 = '%s', Value2 = '%s' + where ID = %s""" % (self.TblDsc.Table, ConvertToSqlString2(List[0]), ConvertToSqlString2(List[1]), Record[3]) + self.TblDsc.Exec(SqlCommand) + + ## GenLibraries + # + # Gen Libraries of Dsc + # + # + # @param ContainerFile: The Dsc file full path + # + def GenLibraries(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_LIBRARIES) + Libraries = {} + # + # Get all include files + # + IncludeFiles = QueryDscItem(self.TblDsc, MODEL_META_DATA_INCLUDE, MODEL_EFI_LIBRARY_INSTANCE, self.FileID) + + # + # Get all Libraries + # + RecordSet = QueryDscItem(self.TblDsc, MODEL_EFI_LIBRARY_INSTANCE, -1, self.FileID) + + # + # Go through each arch + # + for Arch in DataType.ARCH_LIST: + for IncludeFile in IncludeFiles: + if IncludeFile[1] == Arch or IncludeFile[1] == TAB_ARCH_COMMON.upper(): + Filename = CheckFileExist(self.WorkspaceDir, IncludeFile[0], ContainerFile, TAB_LIBRARIES, '', IncludeFile[2]) + for NewItem in open(Filename, 'r').readlines(): + if CleanString(NewItem) == '': + continue + MergeArches(Libraries, NewItem, Arch) + + for Record in RecordSet: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON.upper(): + MergeArches(Libraries, Record[0], Arch) + + for Key in Libraries.keys(): + Library = PlatformLibraryClass() + Library.FilePath = NormPath(Key) + Library.SupArchList = Libraries[Key] + self.Platform.Libraries.LibraryList.append(Library) + + ## GenLibraryClasses + # + # Get LibraryClasses of Dsc + # | + # + # @param ContainerFile: The Dsc file full path + # + def GenLibraryClasses(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_LIBRARY_CLASSES) + LibraryClasses = {} + # + # Get all include files + # + IncludeFiles = QueryDscItem(self.TblDsc, MODEL_META_DATA_INCLUDE, MODEL_EFI_LIBRARY_CLASS, self.FileID) + + # + # Get all LibraryClasses + # + RecordSet = QueryDscItem(self.TblDsc, MODEL_EFI_LIBRARY_CLASS, -1, self.FileID) + + # + # Go through each arch + # + for Arch in DataType.ARCH_LIST: + for IncludeFile in IncludeFiles: + if IncludeFile[1] == Arch or IncludeFile[1] == TAB_ARCH_COMMON.upper(): + Filename = CheckFileExist(self.WorkspaceDir, IncludeFile[0], ContainerFile, TAB_LIBRARY_CLASSES, '', IncludeFile[2]) + for NewItem in open(Filename, 'r').readlines(): + if CleanString(NewItem) == '': + continue + MergeArches(LibraryClasses, GetLibraryClass([NewItem, IncludeFile[4]], Filename, self.WorkspaceDir, -1), Arch) + + for Record in RecordSet: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON.upper(): + (LibClassName, LibClassIns, SupModelList) = GetLibraryClass([Record[0], Record[4]], ContainerFile, self.WorkspaceDir, Record[2]) + MergeArches(LibraryClasses, (LibClassName, LibClassIns, SupModelList), Arch) + # + # Update to Database + # + if self.IsToDatabase: + SqlCommand = """update %s set Value1 = '%s', Value2 = '%s', Value3 = '%s' + where ID = %s""" % (self.TblDsc.Table, ConvertToSqlString2(LibClassName), ConvertToSqlString2(LibClassIns), ConvertToSqlString2(SupModelList), Record[3]) + self.TblDsc.Exec(SqlCommand) + + for Key in LibraryClasses.keys(): + Library = PlatformLibraryClass() + Library.Name = Key[0] + Library.FilePath = NormPath(Key[1]) + Library.SupModuleList = GetSplitValueList(Key[2]) + Library.SupArchList = LibraryClasses[Key] + self.Platform.LibraryClasses.LibraryList.append(Library) + + ## Gen Pcds + # + # Gen Pcd of Dsc as .|[||] + # + # @param Type: The type of Pcd + # @param ContainerFile: The file which describes the pcd, used for error report + # + def GenPcds(self, Type = '', ContainerFile = ''): + Pcds = {} + if Type == DataType.TAB_PCDS_PATCHABLE_IN_MODULE: + Model = MODEL_PCD_PATCHABLE_IN_MODULE + elif Type == DataType.TAB_PCDS_FIXED_AT_BUILD: + Model = MODEL_PCD_FIXED_AT_BUILD + else: + pass + EdkLogger.debug(2, "Generate %s ..." % Type) + + # + # Get all include files + # + IncludeFiles = QueryDscItem(self.TblDsc, MODEL_META_DATA_INCLUDE, Model, self.FileID) + + # + # Get all Pcds + # + RecordSet = QueryDscItem(self.TblDsc, Model, -1, self.FileID) + + # + # Go through each arch + # + for Arch in DataType.ARCH_LIST: + for IncludeFile in IncludeFiles: + if IncludeFile[1] == Arch or IncludeFile[1] == TAB_ARCH_COMMON.upper(): + Filename = CheckFileExist(self.WorkspaceDir, IncludeFile[0], ContainerFile, Type, '', IncludeFile[2]) + for NewItem in open(Filename, 'r').readlines(): + if CleanString(NewItem) == '': + continue + (TokenName, TokenGuidCName, Value, DatumType, MaxDatumSize, Type) = GetPcd(NewItem, Type, Filename, -1) + MergeArches(Pcds, (TokenName, TokenGuidCName, Value, DatumType, MaxDatumSize, Type), Arch) + self.PcdToken[Record[3]] = (TokenGuidCName, TokenName) + + for Record in RecordSet: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON.upper(): + (TokenName, TokenGuidCName, Value, DatumType, MaxDatumSize, Type) = GetPcd(Record[0], Type, ContainerFile, Record[2]) + MergeArches(Pcds, (TokenName, TokenGuidCName, Value, DatumType, MaxDatumSize, Type), Arch) + self.PcdToken[Record[3]] = (TokenGuidCName, TokenName) + + for Key in Pcds: + Pcd = PcdClass(Key[0], '', Key[1], Key[3], Key[4], Key[2], Key[5], [], {}, []) + Pcd.SupArchList = Pcds[Key] + self.Platform.DynamicPcdBuildDefinitions.append(Pcd) + + ## Gen FeatureFlagPcds + # + # Gen FeatureFlagPcds of Dsc file as .|TRUE/FALSE + # + # @param Type: The type of Pcd + # @param ContainerFile: The file which describes the pcd, used for error report + # + def GenFeatureFlagPcds(self, Type = '', ContainerFile = ''): + Pcds = {} + if Type == DataType.TAB_PCDS_FEATURE_FLAG: + Model = MODEL_PCD_FEATURE_FLAG + else: + pass + EdkLogger.debug(2, "Generate %s ..." % Type) + + # + # Get all include files + # + IncludeFiles = QueryDscItem(self.TblDsc, MODEL_META_DATA_INCLUDE, Model, self.FileID) + + # + # Get all FeatureFlagPcds + # + RecordSet = QueryDscItem(self.TblDsc, Model, -1, self.FileID) + + # + # Go through each arch + # + for Arch in DataType.ARCH_LIST: + for IncludeFile in IncludeFiles: + if IncludeFile[1] == Arch or IncludeFile[1] == TAB_ARCH_COMMON.upper(): + Filename = CheckFileExist(self.WorkspaceDir, IncludeFile[0], ContainerFile, Type, '', IncludeFile[2]) + for NewItem in open(Filename, 'r').readlines(): + if CleanString(NewItem) == '': + continue + (TokenName, TokenGuidCName, Value, Type) = GetFeatureFlagPcd(NewItem, Type, Filename, -1) + MergeArches(Pcds, (TokenName, TokenGuidCName, Value, Type), Arch) + self.PcdToken[Record[3]] = (TokenGuidCName, TokenName) + + for Record in RecordSet: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON.upper(): + (TokenName, TokenGuidCName, Value, Type) = GetFeatureFlagPcd(Record[0], Type, ContainerFile, Record[2]) + MergeArches(Pcds, (TokenName, TokenGuidCName, Value, Type), Arch) + self.PcdToken[Record[3]] = (TokenGuidCName, TokenName) + + for Key in Pcds: + Pcd = PcdClass(Key[0], '', Key[1], '', '', Key[2], Key[3], [], {}, []) + Pcd.SupArchList = Pcds[Key] + self.Platform.DynamicPcdBuildDefinitions.append(Pcd) + + ## Gen DynamicDefaultPcds + # + # Gen DynamicDefaultPcds of Dsc as .|[|[|]] + # + # @param Type: The type of Pcd + # @param ContainerFile: The file which describes the pcd, used for error report + # + def GenDynamicDefaultPcds(self, Type = '', ContainerFile = ''): + Pcds = {} + SkuInfoList = {} + if Type == DataType.TAB_PCDS_DYNAMIC_DEFAULT: + Model = MODEL_PCD_DYNAMIC_DEFAULT + elif Type == DataType.TAB_PCDS_DYNAMIC_EX_DEFAULT: + Model = MODEL_PCD_DYNAMIC_EX_DEFAULT + else: + pass + EdkLogger.debug(2, "Generate %s ..." % Type) + + # + # Get all include files + # + IncludeFiles = QueryDscItem(self.TblDsc, MODEL_META_DATA_INCLUDE, Model, self.FileID) + + # + # Get all DynamicDefaultPcds + # + RecordSet = QueryDscItem(self.TblDsc, Model, -1, self.FileID) + + # + # Go through each arch + # + for Arch in DataType.ARCH_LIST: + for IncludeFile in IncludeFiles: + if IncludeFile[1] == Arch or IncludeFile[1] == TAB_ARCH_COMMON.upper(): + Filename = CheckFileExist(self.WorkspaceDir, IncludeFile[0], ContainerFile, Type, '', IncludeFile[2]) + for NewItem in open(Filename, 'r').readlines(): + if CleanString(NewItem) == '': + continue + (K1, K2, K3, K4, K5, K6) = GetDynamicDefaultPcd(NewItem, Type, Filename, -1) + MergeArches(Pcds, (K1, K2, K3, K4, K5, K6, IncludeFile[4]), Arch) + self.PcdToken[Record[3]] = (K2, K1) + + for Record in RecordSet: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON.upper(): + (K1, K2, K3, K4, K5, K6) = GetDynamicDefaultPcd(Record[0], Type, ContainerFile, Record[2]) + MergeArches(Pcds, (K1, K2, K3, K4, K5, K6, Record[4]), Arch) + self.PcdToken[Record[3]] = (K2, K1) + + for Key in Pcds: + (Status, SkuInfoList) = self.GenSkuInfoList(Key[6], self.Platform.SkuInfos.SkuInfoList, '', '', '', '', '', Key[2]) + if Status == False: + ErrorMsg = "The SKUID '%s' used in section '%s' is not defined in section [SkuIds]" % (SkuInfoList, Type) + EdkLogger.error("DSC File Parser", PARSER_ERROR, ErrorMsg, ContainerFile, RaiseError = EdkLogger.IsRaiseError) + Pcd = PcdClass(Key[0], '', Key[1], Key[3], Key[4], Key[2], Key[5], [], SkuInfoList, []) + Pcd.SupArchList = Pcds[Key] + self.Platform.DynamicPcdBuildDefinitions.append(Pcd) + + ## Gen DynamicHiiPcds + # + # Gen DynamicHiiPcds of Dsc as .|||[|[|]] + # + # @param Type: The type of Pcd + # @param ContainerFile: The file which describes the pcd, used for error report + # + def GenDynamicHiiPcds(self, Type = '', ContainerFile = ''): + Pcds = {} + SkuInfoList = {} + if Type == DataType.TAB_PCDS_DYNAMIC_HII: + Model = MODEL_PCD_DYNAMIC_HII + elif Type == DataType.TAB_PCDS_DYNAMIC_EX_HII: + Model = MODEL_PCD_DYNAMIC_EX_HII + else: + pass + EdkLogger.debug(2, "Generate %s ..." % Type) + + # + # Get all include files + # + IncludeFiles = QueryDscItem(self.TblDsc, MODEL_META_DATA_INCLUDE, Model, self.FileID) + + # + # Get all DynamicHiiPcds + # + RecordSet = QueryDscItem(self.TblDsc, Model, -1, self.FileID) + + # + # Go through each arch + # + for Arch in DataType.ARCH_LIST: + for IncludeFile in IncludeFiles: + if IncludeFile[1] == Arch or IncludeFile[1] == TAB_ARCH_COMMON.upper(): + Filename = CheckFileExist(self.WorkspaceDir, IncludeFile[0], ContainerFile, Type, '', IncludeFile[2]) + for NewItem in open(Filename, 'r').readlines(): + if CleanString(NewItem) == '': + continue + (K1, K2, K3, K4, K5, K6, K7, K8) = GetDynamicHiiPcd(NewItem, Type, Filename, -1) + MergeArches(Pcds, (K1, K2, K3, K4, K5, K6, K7, K8, IncludeFile[4]), Arch) + self.PcdToken[Record[3]] = (K2, K1) + + for Record in RecordSet: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON.upper(): + (K1, K2, K3, K4, K5, K6, K7, K8) = GetDynamicHiiPcd(Record[0], Type, ContainerFile, Record[2]) + MergeArches(Pcds, (K1, K2, K3, K4, K5, K6, K7, K8, Record[4]), Arch) + self.PcdToken[Record[3]] = (K2, K1) + + for Key in Pcds: + (Status, SkuInfoList) = self.GenSkuInfoList(Key[8], self.Platform.SkuInfos.SkuInfoList, Key[2], Key[3], Key[4], Key[5], '', '') + if Status == False: + ErrorMsg = "The SKUID '%s' used in section '%s' is not defined in section [SkuIds]" % (SkuInfoList, Type) + EdkLogger.error("DSC File Parser", PARSER_ERROR, ErrorMsg, ContainerFile, RaiseError = EdkLogger.IsRaiseError) + Pcd = PcdClass(Key[0], '', Key[1], '', Key[6], Key[5], Key[7], [], SkuInfoList, []) + Pcd.SupArchList = Pcds[Key] + self.Platform.DynamicPcdBuildDefinitions.append(Pcd) + + ## Gen DynamicVpdPcds + # + # Gen DynamicVpdPcds of Dsc as .|[|] + # + # @param Type: The type of Pcd + # @param ContainerFile: The file which describes the pcd, used for error report + # + def GenDynamicVpdPcds(self, Type = '', ContainerFile = ''): + Pcds = {} + SkuInfoList = {} + if Type == DataType.TAB_PCDS_DYNAMIC_VPD: + Model = MODEL_PCD_DYNAMIC_VPD + elif Type == DataType.TAB_PCDS_DYNAMIC_EX_VPD: + Model = MODEL_PCD_DYNAMIC_EX_VPD + else: + pass + EdkLogger.debug(2, "Generate %s ..." % Type) + + # + # Get all include files + # + IncludeFiles = QueryDscItem(self.TblDsc, MODEL_META_DATA_INCLUDE, Model, self.FileID) + + # + # Get all DynamicVpdPcds + # + RecordSet = QueryDscItem(self.TblDsc, Model, -1, self.FileID) + + # + # Go through each arch + # + for Arch in DataType.ARCH_LIST: + for IncludeFile in IncludeFiles: + if IncludeFile[1] == Arch or IncludeFile[1] == TAB_ARCH_COMMON.upper(): + Filename = CheckFileExist(self.WorkspaceDir, IncludeFile[0], ContainerFile, Type, '', IncludeFile[2]) + for NewItem in open(Filename, 'r').readlines(): + if CleanString(NewItem) == '': + continue + (K1, K2, K3, K4, K5) = GetDynamicVpdPcd(NewItem, Type, Filename, -1) + MergeArches(Pcds, (K1, K2, K3, K4, K5, IncludeFile[4]), Arch) + self.PcdToken[Record[3]] = (K2, K1) + + for Record in RecordSet: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON.upper(): + (K1, K2, K3, K4, K5) = GetDynamicVpdPcd(Record[0], Type, ContainerFile, Record[2]) + MergeArches(Pcds, (K1, K2, K3, K4, K5, Record[4]), Arch) + self.PcdToken[Record[3]] = (K2, K1) + + for Key in Pcds: + (Status, SkuInfoList) = self.GenSkuInfoList(Key[5], self.Platform.SkuInfos.SkuInfoList, '', '', '', '', Key[2], '') + if Status == False: + ErrorMsg = "The SKUID '%s' used in section '%s' is not defined in section [SkuIds]" % (SkuInfoList, Type) + EdkLogger.error("DSC File Parser", PARSER_ERROR, ErrorMsg, ContainerFile, RaiseError = EdkLogger.IsRaiseError) + Pcd = PcdClass(Key[0], '', Key[1], '', Key[3], '', Key[4], [], SkuInfoList, []) + Pcd.SupArchList = Pcds[Key] + self.Platform.DynamicPcdBuildDefinitions.append(Pcd) + + + ## Get Component + # + # Get Component section defined in Dsc file + # + # @param ContainerFile: The file which describes the Components, used for error report + # + # @retval PlatformModuleClass() A instance for PlatformModuleClass + # + def GenComponents(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_COMPONENTS) + Components = sdict() + # + # Get all include files + # + IncludeFiles = QueryDscItem(self.TblDsc, MODEL_META_DATA_INCLUDE, MODEL_META_DATA_COMPONENT, self.FileID) + + # + # Get all Components + # + RecordSet = QueryDscItem(self.TblDsc, MODEL_META_DATA_COMPONENT, -1, self.FileID) + + # + # Go through each arch + # + for Arch in DataType.ARCH_LIST: + for IncludeFile in IncludeFiles: + if IncludeFile[1] == Arch or IncludeFile[1] == TAB_ARCH_COMMON.upper(): + Filename = CheckFileExist(self.WorkspaceDir, IncludeFile[0], ContainerFile, TAB_COMPONENTS, '', IncludeFile[2]) + for NewItem in open(Filename, 'r').readlines(): + if CleanString(NewItem) == '': + continue + NewItems = [] + GetComponents(open(Filename, 'r').read(), TAB_COMPONENTS, NewItems, TAB_COMMENT_SPLIT) + for NewComponent in NewItems: + MergeArches(Components, self.GenComponent(NewComponent, Filename), Arch) + + for Record in RecordSet: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON.upper(): + Lib, Bo, Pcd = [], [], [] + + SubLibSet = QueryDscItem(self.TblDsc, MODEL_EFI_LIBRARY_CLASS, Record[3], self.FileID) + for SubLib in SubLibSet: + Lib.append(TAB_VALUE_SPLIT.join([SubLib[0],SubLib[4]])) + + SubBoSet = QueryDscItem(self.TblDsc, MODEL_META_DATA_BUILD_OPTION, Record[3], self.FileID) + for SubBo in SubBoSet: + Bo.append(SubBo[0]) + + SubPcdSet1 = QueryDscItem(self.TblDsc, MODEL_PCD_FIXED_AT_BUILD, Record[3], self.FileID) + SubPcdSet2 = QueryDscItem(self.TblDsc, MODEL_PCD_PATCHABLE_IN_MODULE, Record[3], self.FileID) + SubPcdSet3 = QueryDscItem(self.TblDsc, MODEL_PCD_FEATURE_FLAG, Record[3], self.FileID) + SubPcdSet4 = QueryDscItem(self.TblDsc, MODEL_PCD_DYNAMIC_EX_DEFAULT, Record[3], self.FileID) + SubPcdSet5 = QueryDscItem(self.TblDsc, MODEL_PCD_DYNAMIC_DEFAULT, Record[3], self.FileID) + for SubPcd in SubPcdSet1: + Pcd.append([DataType.TAB_PCDS_FIXED_AT_BUILD, SubPcd[0], SubPcd[3]]) + for SubPcd in SubPcdSet2: + Pcd.append([DataType.TAB_PCDS_PATCHABLE_IN_MODULE, SubPcd[0], SubPcd[3]]) + for SubPcd in SubPcdSet3: + Pcd.append([DataType.TAB_PCDS_FEATURE_FLAG, SubPcd[0], SubPcd[3]]) + for SubPcd in SubPcdSet4: + Pcd.append([DataType.TAB_PCDS_DYNAMIC_EX, SubPcd[0], SubPcd[3]]) + for SubPcd in SubPcdSet5: + Pcd.append([DataType.TAB_PCDS_DYNAMIC, SubPcd[0], SubPcd[3]]) + Item = [Record[0], Lib, Bo, Pcd] + MergeArches(Components, self.GenComponent(Item, ContainerFile), Arch) + + for Key in Components.keys(): + Key.SupArchList = Components[Key] + self.Platform.Modules.ModuleList.append(Key) + + ## Get Component + # + # Get Component section defined in Dsc file + # + # @param Item: Contents includes a component block + # @param ContainerFile: The file which describes the library class, used for error report + # + # @retval PlatformModuleClass() A instance for PlatformModuleClass + # + def GenComponent(self, Item, ContainerFile, LineNo = -1): + (InfFilename, ExecFilename) = GetExec(Item[0]) + LibraryClasses = Item[1] + BuildOptions = Item[2] + Pcds = Item[3] + Component = PlatformModuleClass() + Component.FilePath = NormPath(InfFilename) + Component.ExecFilePath = NormPath(ExecFilename) + CheckFileType(Component.FilePath, '.Inf', ContainerFile, 'component name', Item[0], LineNo) + CheckFileExist(self.WorkspaceDir, Component.FilePath, ContainerFile, 'component', Item[0], LineNo) + for Lib in LibraryClasses: + List = GetSplitValueList(Lib) + if len(List) != 2: + RaiseParserError(Lib, 'LibraryClasses', ContainerFile, '|') + LibName = List[0] + LibFile = NormPath(List[1]) + if LibName == "" or LibName == "NULL": + LibName = "NULL%d" % self._NullClassIndex + self._NullClassIndex += 1 + CheckFileType(List[1], '.Inf', ContainerFile, 'library instance of component ', Lib, LineNo) + CheckFileExist(self.WorkspaceDir, LibFile, ContainerFile, 'library instance of component', Lib, LineNo) + Component.LibraryClasses.LibraryList.append(PlatformLibraryClass(LibName, LibFile)) + for BuildOption in BuildOptions: + Key = GetBuildOption(BuildOption, ContainerFile) + Component.ModuleSaBuildOption.BuildOptionList.append(BuildOptionClass(Key[0], Key[1], Key[2])) + for Pcd in Pcds: + Type = Pcd[0] + List = GetSplitValueList(Pcd[1]) + PcdId = Pcd[2] + + TokenInfo = None + # + # For FeatureFlag + # + if Type == DataType.TAB_PCDS_FEATURE_FLAG: + if len(List) != 2: + RaiseParserError(Pcd[1], 'Components', ContainerFile, '.|TRUE/FALSE') + + CheckPcdTokenInfo(List[0], 'Components', ContainerFile) + TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT) + Component.PcdBuildDefinitions.append(PcdClass(TokenInfo[1], '', TokenInfo[0], '', '', List[1], Type, [], {}, [])) + # + # For FixedAtBuild or PatchableInModule + # + if Type == DataType.TAB_PCDS_FIXED_AT_BUILD or Type == DataType.TAB_PCDS_PATCHABLE_IN_MODULE: + List.append('') + if len(List) != 3 and len(List) != 4: + RaiseParserError(Pcd[1], 'Components', ContainerFile, '.|[|]') + + CheckPcdTokenInfo(List[0], 'Components', ContainerFile) + TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT) + Component.PcdBuildDefinitions.append(PcdClass(TokenInfo[1], '', TokenInfo[0], '', List[2], List[1], Type, [], {}, [])) + + # + # For Dynamic or DynamicEx + # + if Type == DataType.TAB_PCDS_DYNAMIC or Type == DataType.TAB_PCDS_DYNAMIC_EX: + if len(List) != 1: + RaiseParserError(Pcd[1], 'Components', ContainerFile, '.') + + CheckPcdTokenInfo(List[0], 'Components', ContainerFile) + TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT) + Component.PcdBuildDefinitions.append(PcdClass(TokenInfo[1], '', TokenInfo[0], '', '', '', Type, [], {}, [])) + + # + # Add to PcdToken + # + self.PcdToken[PcdId] = (TokenInfo[0], TokenInfo[1]) + + return Component + #End of GenComponent + + ## Gen SkuInfoList + # + # Gen SkuInfoList section defined in Dsc file + # + # @param SkuNameList: Input value for SkuNameList + # @param SkuInfo: Input value for SkuInfo + # @param VariableName: Input value for VariableName + # @param VariableGuid: Input value for VariableGuid + # @param VariableOffset: Input value for VariableOffset + # @param HiiDefaultValue: Input value for HiiDefaultValue + # @param VpdOffset: Input value for VpdOffset + # @param DefaultValue: Input value for DefaultValue + # + # @retval (False, SkuName) Not found in section SkuId Dsc file + # @retval (True, SkuInfoList) Found in section SkuId of Dsc file + # + def GenSkuInfoList(self, SkuNameList, SkuInfo, VariableName = '', VariableGuid = '', VariableOffset = '', HiiDefaultValue = '', VpdOffset = '', DefaultValue = ''): + SkuNameList = GetSplitValueList(SkuNameList) + if SkuNameList == None or SkuNameList == [] or SkuNameList == ['']: + SkuNameList = ['DEFAULT'] + SkuInfoList = {} + for Item in SkuNameList: + if Item not in SkuInfo: + return False, Item + Sku = SkuInfoClass(Item, SkuInfo[Item], VariableName, VariableGuid, VariableOffset, HiiDefaultValue, VpdOffset, DefaultValue) + SkuInfoList[Item] = Sku + + return True, SkuInfoList + + ## Parse Include statement + # + # Get include file path + # + # 1. Insert a record into TblFile ??? + # 2. Insert a record into TblDsc + # Value1: IncludeFilePath + # + # @param LineValue: The line of incude statement + def ParseInclude(self, LineValue, StartLine, Table, FileID, Filename, SectionName, Model, Arch): + EdkLogger.debug(EdkLogger.DEBUG_2, "!include statement '%s' found in section %s" % (LineValue, SectionName)) + SectionModel = Section[SectionName.upper()] + IncludeFile = CleanString(LineValue[LineValue.upper().find(DataType.TAB_INCLUDE.upper() + ' ') + len(DataType.TAB_INCLUDE + ' ') : ]) + Table.Insert(Model, IncludeFile, '', '', Arch, SectionModel, FileID, StartLine, -1, StartLine, -1, 0) + + ## Parse DEFINE statement + # + # Get DEFINE macros + # + # 1. Insert a record into TblDsc + # Value1: Macro Name + # Value2: Macro Value + # + def ParseDefine(self, LineValue, StartLine, Table, FileID, Filename, SectionName, Model, Arch): + EdkLogger.debug(EdkLogger.DEBUG_2, "DEFINE statement '%s' found in section %s" % (LineValue, SectionName)) + SectionModel = Section[SectionName.upper()] + Define = GetSplitValueList(CleanString(LineValue[LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') + len(DataType.TAB_DEFINE + ' ') : ]), TAB_EQUAL_SPLIT, 1) + Table.Insert(Model, Define[0], Define[1], '', Arch, SectionModel, FileID, StartLine, -1, StartLine, -1, 0) + + ## Parse Defines section + # + # Get one item in defines section + # + # Value1: Item Name + # Value2: Item Value + # + def ParseDefinesSection(self, LineValue, StartLine, Table, FileID, Filename, SectionName, Model, Arch): + EdkLogger.debug(EdkLogger.DEBUG_2, "Parse '%s' found in section %s" % (LineValue, SectionName)) + Defines = GetSplitValueList(LineValue, TAB_EQUAL_SPLIT, 1) + if len(Defines) != 2: + RaiseParserError(LineValue, SectionName, Filename, '', StartLine) + self.TblDsc.Insert(Model, Defines[0], Defines[1], '', Arch, -1, FileID, StartLine, -1, StartLine, -1, 0) + + ## Insert conditional statements + # + # Pop an item from IfDefList + # Insert conditional statements to database + # + # @param Filename: Path of parsing file + # @param IfDefList: A list stored current conditional statements + # @param EndLine: The end line no + # @param ArchList: Support arch list + # + def InsertConditionalStatement(self, Filename, FileID, BelongsToItem, IfDefList, EndLine, ArchList): + (Value1, Value2, Value3, Model, StartColumn, EndColumn, Enabled) = ('', '', '', -1, -1, -1, 0) + if IfDefList == []: + ErrorMsg = 'Not suited conditional statement in file %s' % Filename + EdkLogger.error("DSC File Parser", PARSER_ERROR, ErrorMsg, Filename, RaiseError = EdkLogger.IsRaiseError) + else: + # + # Get New Dsc item ID + # + DscID = self.TblDsc.GetCount() + 1 + + # + # Pop the conditional statements which is closed + # + PreviousIf = IfDefList.pop() + EdkLogger.debug(EdkLogger.DEBUG_5, 'Previous IfDef: ' + str(PreviousIf)) + + # + # !ifdef and !ifndef + # + if PreviousIf[2] in (MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF, MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF): + Value1 = PreviousIf[0] + Model = PreviousIf[2] + self.TblDsc.Insert(Model, Value1, Value2, Value3, ArchList, BelongsToItem, self.FileID, PreviousIf[1], StartColumn, EndLine, EndColumn, Enabled) + # + # !if and !elseif + # + elif PreviousIf[2] in (MODEL_META_DATA_CONDITIONAL_STATEMENT_IF, Model): + List = PreviousIf[0].split(' ') + Value1 = List[0] + Value2 = List[1] + Value3 = List[2] + Value3 = SplitString(Value3) + Model = PreviousIf[2] + self.TblDsc.Insert(Model, Value1, Value2, Value3, ArchList, BelongsToItem, self.FileID, PreviousIf[1], StartColumn, EndLine, EndColumn, Enabled) + # + # !else + # + elif PreviousIf[2] in (MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE, Model): + Value1 = PreviousIf[0].strip() + Model = PreviousIf[2] + self.TblDsc.Insert(Model, Value1, Value2, Value3, ArchList, BelongsToItem, self.FileID, PreviousIf[1], StartColumn, EndLine, EndColumn, Enabled) + + ## Load Dsc file + # + # Load the file if it exists + # + # @param Filename: Input value for filename of Dsc file + # + def LoadDscFile(self, Filename): + # + # Insert a record for file + # + Filename = NormPath(Filename) + self.Identification.FileFullPath = Filename + (self.Identification.FileRelativePath, self.Identification.FileName) = os.path.split(Filename) + self.FileID = self.TblFile.InsertFile(Filename, MODEL_FILE_DSC) + + # + # Init DscTable + # + #self.TblDsc.Table = "Dsc%s" % FileID + #self.TblDsc.Create() + + # + # Init common datas + # + IfDefList, SectionItemList, CurrentSection, ArchList, ThirdList, IncludeFiles = \ + [], [], TAB_UNKNOWN, [], [], [] + LineNo = 0 + + # + # Parse file content + # + IsFindBlockComment = False + ReservedLine = '' + for Line in open(Filename, 'r'): + LineNo = LineNo + 1 + # + # Remove comment block + # + if Line.find(TAB_COMMENT_R8_START) > -1: + ReservedLine = GetSplitValueList(Line, TAB_COMMENT_R8_START, 1)[0] + IsFindBlockComment = True + if Line.find(TAB_COMMENT_R8_END) > -1: + Line = ReservedLine + GetSplitValueList(Line, TAB_COMMENT_R8_END, 1)[1] + ReservedLine = '' + IsFindBlockComment = False + if IsFindBlockComment: + continue + + # + # Remove comments at tail and remove spaces again + # + Line = CleanString(Line) + if Line == '': + continue + + # + # Find a new section tab + # First insert previous section items + # And then parse the content of the new section + # + if Line.startswith(TAB_SECTION_START) and Line.endswith(TAB_SECTION_END): + # + # Insert items data of previous section + # + self.InsertSectionItemsIntoDatabase(self.FileID, Filename, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList) + # + # Parse the new section + # + SectionItemList = [] + ArchList = [] + ThirdList = [] + + CurrentSection = '' + LineList = GetSplitValueList(Line[len(TAB_SECTION_START):len(Line) - len(TAB_SECTION_END)], TAB_COMMA_SPLIT) + for Item in LineList: + ItemList = GetSplitValueList(Item, TAB_SPLIT) + if CurrentSection == '': + CurrentSection = ItemList[0] + else: + if CurrentSection != ItemList[0]: + EdkLogger.error("Parser", PARSER_ERROR, "Different section names '%s' and '%s' are found in one section definition, this is not allowed." % (CurrentSection, ItemList[0]), File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError) + if CurrentSection.upper() not in self.KeyList: + RaiseParserError(Line, CurrentSection, Filename, '', LineNo) + CurrentSection = TAB_UNKNOWN + continue + ItemList.append('') + ItemList.append('') + if len(ItemList) > 5: + RaiseParserError(Line, CurrentSection, Filename, '', LineNo) + else: + if ItemList[1] != '' and ItemList[1].upper() not in ARCH_LIST_FULL: + EdkLogger.error("Parser", PARSER_ERROR, "Invalid Arch definition '%s' found" % ItemList[1], File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError) + ArchList.append(ItemList[1].upper()) + ThirdList.append(ItemList[2]) + + continue + + # + # Not in any defined section + # + if CurrentSection == TAB_UNKNOWN: + ErrorMsg = "%s is not in any defined section" % Line + EdkLogger.error("Parser", PARSER_ERROR, ErrorMsg, File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError) + + # + # Add a section item + # + SectionItemList.append([Line, LineNo]) + # End of parse + #End of For + + # + # Insert items data of last section + # + self.InsertSectionItemsIntoDatabase(self.FileID, Filename, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList) + + # + # Parse conditional statements + # + self.ParseConditionalStatement() + + # + # Replace all DEFINE macros with its actual values + # + #ParseDefineMacro2(self.TblDsc, self.RecordSet, GlobalData.gGlobalDefines) + ParseDefineMacro(self.TblDsc, GlobalData.gGlobalDefines) + + + ## ParseConditionalStatement + # + # Search all conditional statement and disable no match records + # + def ParseConditionalStatement(self): + # + # Disabled all !if/!elif/!ifdef statements without DEFINE + # + SqlCommand = """select A.StartLine, A.EndLine from %s as A + where A.Model in (%s, %s, %s) + and A.Enabled = 0 + and A.BelongsToFile = %s + and A.Value1 not in (select B.Value1 from %s as B + where B.Model = %s + and B.Enabled = 0 + and A.StartLine > B.StartLine + and A.Arch = B.Arch + and A.BelongsToItem = B.BelongsToItem + and A.BelongsToFile = B.BelongsToFile) """ % \ + (self.TblDsc.Table, \ + MODEL_META_DATA_CONDITIONAL_STATEMENT_IF, MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE, MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF, \ + self.FileID, \ + self.TblDsc.Table, \ + MODEL_META_DATA_DEFINE) + RecordSet = self.TblDsc.Exec(SqlCommand) + for Record in RecordSet: + SqlCommand = """Update %s set Enabled = -1 where StartLine >= %s and EndLine <= %s""" %(self.TblDsc.Table, Record[0], Record[1]) + self.TblDsc.Exec(SqlCommand) + + # + # Disabled !ifndef with DEFINE + # + SqlCommand = """select A.StartLine, A.EndLine from %s as A + where A.Model = %s + and A.Enabled = 0 + and A.BelongsToFile = %s + and A.Value1 in (select B.Value1 from %s as B + where B.Model = %s + and B.Enabled = 0 + and A.StartLine > B.StartLine + and A.Arch = B.Arch + and A.BelongsToItem = B.BelongsToItem + and A.BelongsToFile = B.BelongsToFile)""" % \ + (self.TblDsc.Table, \ + MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF, \ + self.FileID, \ + self.TblDsc.Table, \ + MODEL_META_DATA_DEFINE) + RecordSet = self.TblDsc.Exec(SqlCommand) + for Record in RecordSet: + SqlCommand = """Update %s set Enabled = -1 where StartLine >= %s and EndLine <= %s""" %(self.TblDsc.Table, Record[0], Record[1]) + EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand) + self.Cur.execute(SqlCommand) + + # + # Disabled !if, !elif and !else with un-match value + # + SqlCommand = """select A.Model, A.Value1, A.Value2, A.Value3, A.StartLine, A.EndLine, B.Value2 from %s as A join %s as B + where A.Model in (%s, %s) + and A.Enabled = 0 + and A.BelongsToFile = %s + and B.Enabled = 0 + and B.Model = %s + and A.Value1 = B.Value1 + and A.StartLine > B.StartLine + and A.BelongsToItem = B.BelongsToItem + and A.BelongsToFile = B.BelongsToFile""" % \ + (self.TblDsc.Table, self.TblDsc.Table, \ + MODEL_META_DATA_CONDITIONAL_STATEMENT_IF, MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE, \ + self.FileID, MODEL_META_DATA_DEFINE) + RecordSet = self.TblDsc.Exec(SqlCommand) + DisabledList = [] + for Record in RecordSet: + if Record[0] == MODEL_META_DATA_CONDITIONAL_STATEMENT_IF: + if not self.Compare(Record[6], Record[2], Record[3]): + SqlCommand = """Update %s set Enabled = -1 where StartLine >= %s and EndLine <= %s""" %(self.TblDsc.Table, Record[4], Record[5]) + self.TblDsc.Exec(SqlCommand) + else: + DisabledList.append(Record[1]) + continue + if Record[0] == MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE and Record[1] in DisabledList: + SqlCommand = """Update %s set Enabled = -1 where StartLine >= %s and EndLine <= %s""" %(self.TblDsc.Table, Record[4], Record[5]) + self.TblDsc.Exec(SqlCommand) + + ## Compare + # + # Compare two values + # @param Value1: + # @param CompareType: + # @param Value2: + # + def Compare(self, Value1, CompareType, Value2): + Command = """Value1 %s Value2""" %CompareType + return eval(Command) + + ## First time to insert records to database + # + # Insert item data of a section to database + # @param FileID: The ID of belonging file + # @param Filename: The name of belonging file + # @param CurrentSection: The name of currect section + # @param SectionItemList: A list of items of the section + # @param ArchList: A list of arches + # @param ThirdList: A list of third parameters, ModuleType for LibraryClass and SkuId for Dynamic Pcds + # @param IfDefList: A list of all conditional statements + # + def InsertSectionItemsIntoDatabase(self, FileID, Filename, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList): + # + # Insert each item data of a section + # + for Index in range(0, len(ArchList)): + Arch = ArchList[Index] + Third = ThirdList[Index] + if Arch == '': + Arch = TAB_ARCH_COMMON.upper() + + Model = Section[CurrentSection.upper()] + #Records = self.RecordSet[Model] + + for SectionItem in SectionItemList: + BelongsToItem, EndLine, EndColumn = -1, -1, -1 + LineValue, StartLine, EndLine = SectionItem[0], SectionItem[1], SectionItem[1] + + + EdkLogger.debug(4, "Parsing %s ..." %LineValue) + # + # Parse '!ifdef' + # + if LineValue.upper().find(TAB_IF_DEF.upper()) > -1: + IfDefList.append((LineValue[len(TAB_IF_N_DEF):].strip(), StartLine, MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF)) + continue + + # + # Parse '!ifndef' + # + if LineValue.upper().find(TAB_IF_N_DEF.upper()) > -1: + IfDefList.append((LineValue[len(TAB_IF_N_DEF):].strip(), StartLine, MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF)) + continue + + # + # Parse '!endif' + # + if LineValue.upper().find(TAB_END_IF.upper()) > -1: + self.InsertConditionalStatement(Filename, FileID, Model, IfDefList, StartLine, Arch) + continue + # + # Parse '!if' + # + if LineValue.upper().find(TAB_IF.upper()) > -1: + IfDefList.append((LineValue[len(TAB_IF):].strip(), StartLine, MODEL_META_DATA_CONDITIONAL_STATEMENT_IF)) + continue + + # + # Parse '!elseif' + # + if LineValue.upper().find(TAB_ELSE_IF.upper()) > -1: + self.InsertConditionalStatement(Filename, FileID, Model, IfDefList, StartLine - 1, Arch) + IfDefList.append((LineValue[len(TAB_ELSE_IF):].strip(), StartLine, MODEL_META_DATA_CONDITIONAL_STATEMENT_IF)) + continue + + # + # Parse '!else' + # + if LineValue.upper().find(TAB_ELSE.upper()) > -1: + Key = IfDefList[-1][0].split(' ' , 1)[0].strip() + self.InsertConditionalStatement(Filename, FileID, Model, IfDefList, StartLine, Arch) + IfDefList.append((Key, StartLine, MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE)) + continue + + # + # Parse !include statement first + # + if LineValue.upper().find(DataType.TAB_INCLUDE.upper() + ' ') > -1: + self.ParseInclude(LineValue, StartLine, self.TblDsc, FileID, Filename, CurrentSection, MODEL_META_DATA_INCLUDE, Arch) + continue + + # + # And then parse DEFINE statement + # + if LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') > -1: + self.ParseDefine(LineValue, StartLine, self.TblDsc, FileID, Filename, CurrentSection, MODEL_META_DATA_DEFINE, Arch) + continue + + # + # At last parse other sections + # + if CurrentSection == TAB_LIBRARY_CLASSES or CurrentSection in TAB_PCD_DYNAMIC_TYPE_LIST or CurrentSection in TAB_PCD_DYNAMIC_EX_TYPE_LIST: + ID = self.TblDsc.Insert(Model, LineValue, Third, '', Arch, -1, FileID, StartLine, -1, StartLine, -1, 0) + #Records.append([LineValue, Arch, StartLine, ID, Third]) + continue + elif CurrentSection != TAB_COMPONENTS: + ID = self.TblDsc.Insert(Model, LineValue, '', '', Arch, -1, FileID, StartLine, -1, StartLine, -1, 0) + #Records.append([LineValue, Arch, StartLine, ID, Third]) + continue + + # + # Parse COMPONENT section + # + if CurrentSection == TAB_COMPONENTS: + Components = [] + GetComponent(SectionItemList, Components) + for Component in Components: + EdkLogger.debug(4, "Parsing component %s ..." %Component) + DscItmeID = self.TblDsc.Insert(MODEL_META_DATA_COMPONENT, Component[0], '', '', Arch, -1, FileID, StartLine, -1, StartLine, -1, 0) + for Item in Component[1]: + List = GetSplitValueList(Item, MaxSplit = 2) + LibName, LibIns = '', '' + if len(List) == 2: + LibName = List[0] + LibIns = List[1] + else: + LibName = List[0] + self.TblDsc.Insert(MODEL_EFI_LIBRARY_CLASS, LibName, LibIns, '', Arch, DscItmeID, FileID, StartLine, -1, StartLine, -1, 0) + for Item in Component[2]: + self.TblDsc.Insert(MODEL_META_DATA_BUILD_OPTION, Item, '', '', Arch, DscItmeID, FileID, StartLine, -1, StartLine, -1, 0) + for Item in Component[3]: + Model = Section[Item[0].upper()] + self.TblDsc.Insert(Model, Item[1], '', '', Arch, DscItmeID, FileID, StartLine, -1, StartLine, -1, 0) + + ## Show detailed information of Dsc + # + # Print all members and their values of Dsc class + # + def ShowDsc(self): + print TAB_SECTION_START + TAB_INF_DEFINES + TAB_SECTION_END + printDict(self.Defines.DefinesDictionary) + + for Key in self.KeyList: + for Arch in DataType.ARCH_LIST_FULL: + Command = "printList(TAB_SECTION_START + '" + \ + Key + DataType.TAB_SPLIT + Arch + \ + "' + TAB_SECTION_END, self.Contents[arch]." + Key + ')' + eval(Command) + + ## Show detailed information of Platform + # + # Print all members and their values of Platform class + # + def ShowPlatform(self): + M = self.Platform + for Arch in M.Header.keys(): + print '\nArch =', Arch + print 'Filename =', M.Header[Arch].FileName + print 'FullPath =', M.Header[Arch].FullPath + print 'BaseName =', M.Header[Arch].Name + print 'Guid =', M.Header[Arch].Guid + print 'Version =', M.Header[Arch].Version + print 'DscSpecification =', M.Header[Arch].DscSpecification + print 'SkuId =', M.Header[Arch].SkuIdName + print 'SupArchList =', M.Header[Arch].SupArchList + print 'BuildTargets =', M.Header[Arch].BuildTargets + print 'OutputDirectory =', M.Header[Arch].OutputDirectory + print 'BuildNumber =', M.Header[Arch].BuildNumber + print 'MakefileName =', M.Header[Arch].MakefileName + print 'BsBaseAddress =', M.Header[Arch].BsBaseAddress + print 'RtBaseAddress =', M.Header[Arch].RtBaseAddress + print 'Define =', M.Header[Arch].Define + print 'Fdf =', M.FlashDefinitionFile.FilePath + print '\nBuildOptions =', M.BuildOptions, M.BuildOptions.IncludeFiles + for Item in M.BuildOptions.BuildOptionList: + print '\t', 'ToolChainFamily =', Item.ToolChainFamily, 'ToolChain =', Item.ToolChain, 'Option =', Item.Option, 'Arch =', Item.SupArchList + print '\nSkuIds =', M.SkuInfos.SkuInfoList, M.SkuInfos.IncludeFiles + print '\nLibraries =', M.Libraries, M.Libraries.IncludeFiles + for Item in M.Libraries.LibraryList: + print '\t', Item.FilePath, Item.SupArchList, Item.Define + print '\nLibraryClasses =', M.LibraryClasses, M.LibraryClasses.IncludeFiles + for Item in M.LibraryClasses.LibraryList: + print '\t', Item.Name, Item.FilePath, Item.SupModuleList, Item.SupArchList, Item.Define + print '\nPcds =', M.DynamicPcdBuildDefinitions + for Item in M.DynamicPcdBuildDefinitions: + print '\tCname=', Item.CName, 'TSG=', Item.TokenSpaceGuidCName, 'Value=', Item.DefaultValue, 'Token=', Item.Token, 'Type=', Item.ItemType, 'Datum=', Item.DatumType, 'Size=', Item.MaxDatumSize, 'Arch=', Item.SupArchList, Item.SkuInfoList + for Sku in Item.SkuInfoList.values(): + print '\t\t', str(Sku) + print '\nComponents =', M.Modules.ModuleList, M.Modules.IncludeFiles + for Item in M.Modules.ModuleList: + print '\t', Item.FilePath, Item.ExecFilePath, Item.SupArchList + for Lib in Item.LibraryClasses.LibraryList: + print '\t\tLib:', Lib.Name, Lib.FilePath + for Bo in Item.ModuleSaBuildOption.BuildOptionList: + print '\t\tBuildOption:', Bo.ToolChainFamily, Bo.ToolChain, Bo.Option + for Pcd in Item.PcdBuildDefinitions: + print '\t\tPcd:', Pcd.CName, Pcd.TokenSpaceGuidCName, Pcd.MaxDatumSize, Pcd.DefaultValue, Pcd.ItemType + +## +# +# 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) + + W = os.getenv('WORKSPACE') + F = os.path.join(W, 'Nt32Pkg/Nt32Pkg.dsc') + + Db = Database.Database('Dsc.db') + Db.InitDatabase() + + P = Dsc(os.path.normpath(F), True, True, W, Db) + P.ShowPlatform() + + Db.Close() diff --git a/BaseTools/Source/Python/Common/EdkIIWorkspace.py b/BaseTools/Source/Python/Common/EdkIIWorkspace.py new file mode 100644 index 0000000000..a494e814a6 --- /dev/null +++ b/BaseTools/Source/Python/Common/EdkIIWorkspace.py @@ -0,0 +1,318 @@ +## @file +# This is the base class for applications that operate on an EDK II Workspace +# +# Copyright (c) 2007, 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 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, sys, time +from DataType import * + +## EdkIIWorkspace +# +# Collect WorkspaceDir from the environment, the Verbose command line flag, and detect an icon bitmap file. +# +# @var StartTime: Time of build system starting +# @var PrintRunTime: Printable time of build system running +# @var PrintRunStatus: Printable status of build system running +# @var RunStatus: Status of build system running +# +class EdkIIWorkspace: + def __init__(self): + self.StartTime = time.time() + self.PrintRunTime = False + self.PrintRunStatus = False + self.RunStatus = '' + + # + # Check environment valiable 'WORKSPACE' + # + if os.environ.get('WORKSPACE') == None: + print 'ERROR: WORKSPACE not defined. Please run EdkSetup from the EDK II install directory.' + return False + + self.CurrentWorkingDir = os.getcwd() + + self.WorkspaceDir = os.path.realpath(os.environ.get('WORKSPACE')) + (Drive, Path) = os.path.splitdrive(self.WorkspaceDir) + if Drive == '': + (Drive, CwdPath) = os.path.splitdrive(self.CurrentWorkingDir) + if Drive != '': + self.WorkspaceDir = Drive + Path + else: + self.WorkspaceDir = Drive.upper() + Path + + self.WorkspaceRelativeWorkingDir = self.WorkspaceRelativePath (self.CurrentWorkingDir) + + try: + # + # Load TianoCoreOrgLogo, used for GUI tool + # + self.Icon = wx.Icon(self.WorkspaceFile('tools/Python/TianoCoreOrgLogo.gif'),wx.BITMAP_TYPE_GIF) + except: + self.Icon = None + + self.Verbose = False + for Arg in sys.argv: + if Arg.lower() == '-v': + self.Verbose = True + + ## Close build system + # + # Close build system and print running time and status + # + def Close(self): + if self.PrintRunTime: + Seconds = int(time.time() - self.StartTime) + if Seconds < 60: + print 'Run Time: %d seconds' % (Seconds) + else: + Minutes = Seconds / 60 + Seconds = Seconds % 60 + if Minutes < 60: + print 'Run Time: %d minutes %d seconds' % (Minutes, Seconds) + else: + Hours = Minutes / 60 + Minutes = Minutes % 60 + print 'Run Time: %d hours %d minutes %d seconds' % (Hours, Minutes, Seconds) + if self.RunStatus != '': + print self.RunStatus + + ## Convert to a workspace relative filename + # + # Convert a full path filename to a workspace relative filename. + # + # @param FileName: The filename to be Converted + # + # @retval None Workspace dir is not found in the full path + # @retval string The relative filename + # + def WorkspaceRelativePath(self, FileName): + FileName = os.path.realpath(FileName) + if FileName.find(self.WorkspaceDir) != 0: + return None + return FileName.replace (self.WorkspaceDir, '').strip('\\').strip('/') + + ## Convert to a full path filename + # + # Convert a workspace relative filename to a full path filename. + # + # @param FileName: The filename to be Converted + # + # @retval string The full path filename + # + def WorkspaceFile(self, FileName): + return os.path.realpath(os.path.join(self.WorkspaceDir,FileName)) + + ## Convert to a real path filename + # + # Convert ${WORKSPACE} to real path + # + # @param FileName: The filename to be Converted + # + # @retval string The full path filename + # + def WorkspacePathConvert(self, FileName): + return os.path.realpath(FileName.replace(TAB_WORKSPACE, self.WorkspaceDir)) + + ## Convert XML into a DOM + # + # Parse an XML file into a DOM and return the DOM. + # + # @param FileName: The filename to be parsed + # + # @retval XmlParseFile (self.WorkspaceFile(FileName)) + # + def XmlParseFile (self, FileName): + if self.Verbose: + print FileName + return XmlParseFile (self.WorkspaceFile(FileName)) + + ## Convert a XML section + # + # Parse a section of an XML file into a DOM(Document Object Model) and return the DOM. + # + # @param FileName: The filename to be parsed + # @param SectionTag: The tag name of the section to be parsed + # + # @retval XmlParseFileSection (self.WorkspaceFile(FileName), SectionTag) + # + def XmlParseFileSection (self, FileName, SectionTag): + if self.Verbose: + print FileName + return XmlParseFileSection (self.WorkspaceFile(FileName), SectionTag) + + ## Save a XML file + # + # Save a DOM(Document Object Model) into an XML file. + # + # @param Dom: The Dom to be saved + # @param FileName: The filename + # + # @retval XmlSaveFile (Dom, self.WorkspaceFile(FileName)) + # + def XmlSaveFile (self, Dom, FileName): + if self.Verbose: + print FileName + return XmlSaveFile (Dom, self.WorkspaceFile(FileName)) + + ## Convert Text File To Dictionary + # + # Convert a workspace relative text file to a dictionary of (name:value) pairs. + # + # @param FileName: Text filename + # @param Dictionary: Dictionary to store data + # @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 + # + # @retval ConvertTextFileToDictionary(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter) + # + def ConvertTextFileToDictionary(self, FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter): + if self.Verbose: + print FileName + return ConvertTextFileToDictionary(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter) + + ## Convert Dictionary To Text File + # + # Convert a dictionary of (name:value) pairs to a workspace relative text file. + # + # @param FileName: Text filename + # @param Dictionary: Dictionary to store data + # @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 + # + # @retval ConvertDictionaryToTextFile(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter) + # + def ConvertDictionaryToTextFile(self, FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter): + if self.Verbose: + print FileName + return ConvertDictionaryToTextFile(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter) + +## Convert Text File To Dictionary +# +# Convert a text file to a dictionary of (name:value) pairs. +# +# @param FileName: Text filename +# @param Dictionary: Dictionary to store data +# @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 +# +# @retval True Convert successfully +# @retval False Open file failed +# +def ConvertTextFileToDictionary(FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter): + try: + F = open(FileName,'r') + except: + return False + Keys = [] + for Line in F: + LineList = Line.split(KeySplitCharacter,1) + if len(LineList) >= 2: + Key = LineList[0].split() + if len(Key) == 1 and Key[0][0] != CommentCharacter and Key[0] not in Keys: + if ValueSplitFlag: + Dictionary[Key[0]] = LineList[1].replace('\\','/').split(ValueSplitCharacter) + else: + Dictionary[Key[0]] = LineList[1].strip().replace('\\','/') + Keys += [Key[0]] + F.close() + return True + +## Convert Dictionary To Text File +# +# Convert a dictionary of (name:value) pairs to a text file. +# +# @param FileName: Text filename +# @param Dictionary: Dictionary to store data +# @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 +# +# @retval True Convert successfully +# @retval False Open file failed +# +def ConvertDictionaryToTextFile(FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter): + try: + F = open(FileName,'r') + Lines = [] + Lines = F.readlines() + F.close() + except: + Lines = [] + Keys = Dictionary.keys() + MaxLength = 0 + for Key in Keys: + if len(Key) > MaxLength: + MaxLength = len(Key) + Index = 0 + for Line in Lines: + LineList = Line.split(KeySplitCharacter,1) + if len(LineList) >= 2: + Key = LineList[0].split() + if len(Key) == 1 and Key[0][0] != CommentCharacter and Key[0] in Dictionary: + if ValueSplitFlag: + Line = '%-*s %c %s\n' % (MaxLength, Key[0], KeySplitCharacter, ' '.join(Dictionary[Key[0]])) + else: + Line = '%-*s %c %s\n' % (MaxLength, Key[0], KeySplitCharacter, Dictionary[Key[0]]) + Lines.pop(Index) + if Key[0] in Keys: + Lines.insert(Index,Line) + Keys.remove(Key[0]) + Index += 1 + for RemainingKey in Keys: + if ValueSplitFlag: + Line = '%-*s %c %s\n' % (MaxLength, RemainingKey, KeySplitCharacter,' '.join(Dictionary[RemainingKey])) + else: + Line = '%-*s %c %s\n' % (MaxLength, RemainingKey, KeySplitCharacter, Dictionary[RemainingKey]) + Lines.append(Line) + try: + F = open(FileName,'w') + except: + return False + F.writelines(Lines) + F.close() + return True + +## Create a new directory +# +# @param Directory: Directory to be created +# +def CreateDirectory(Directory): + if not os.access(Directory, os.F_OK): + os.makedirs (Directory) + +## Create a new file +# +# @param Directory: Directory to be created +# @param FileName: Filename to be created +# @param Mode: The mode of open file, defautl is 'w' +# +def CreateFile(Directory, FileName, Mode='w'): + CreateDirectory (Directory) + return open(os.path.join(Directory, FileName), Mode) + +## +# +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +# +if __name__ == '__main__': + # Nothing to do here. Could do some unit tests + pass \ No newline at end of file diff --git a/BaseTools/Source/Python/Common/EdkIIWorkspaceBuild.py b/BaseTools/Source/Python/Common/EdkIIWorkspaceBuild.py new file mode 100644 index 0000000000..82ab1796ad --- /dev/null +++ b/BaseTools/Source/Python/Common/EdkIIWorkspaceBuild.py @@ -0,0 +1,1669 @@ +## @file +# This file is used to define each component of the build database +# +# Copyright (c) 2007 ~ 2008, 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 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, string, copy, pdb, copy +import EdkLogger +import DataType +from InfClassObject import * +from DecClassObject import * +from DscClassObject import * +from String import * +from BuildToolError import * +from Misc import sdict +import Database as Database +import time as time + +## PcdClassObject +# +# This Class is used for PcdObject +# +# @param object: Inherited from object class +# @param Name: Input value for Name of Pcd, default is None +# @param Guid: Input value for Guid of Pcd, default is None +# @param Type: Input value for Type of Pcd, default is None +# @param DatumType: Input value for DatumType of Pcd, default is None +# @param Value: Input value for Value of Pcd, default is None +# @param Token: Input value for Token of Pcd, default is None +# @param MaxDatumSize: Input value for MaxDatumSize of Pcd, default is None +# @param SkuInfoList: Input value for SkuInfoList of Pcd, default is {} +# @param IsOverrided: Input value for IsOverrided of Pcd, default is False +# +# @var TokenCName: To store value for TokenCName +# @var TokenSpaceGuidCName: To store value for TokenSpaceGuidCName +# @var Type: To store value for Type +# @var DatumType: To store value for DatumType +# @var TokenValue: To store value for TokenValue +# @var MaxDatumSize: To store value for MaxDatumSize +# @var SkuInfoList: To store value for SkuInfoList +# @var IsOverrided: To store value for IsOverrided +# @var Phase: To store value for Phase, default is "DXE" +# +class PcdClassObject(object): + def __init__(self, Name = None, Guid = None, Type = None, DatumType = None, Value = None, Token = None, MaxDatumSize = None, SkuInfoList = {}, IsOverrided = False): + self.TokenCName = Name + self.TokenSpaceGuidCName = Guid + self.Type = Type + self.DatumType = DatumType + self.DefaultValue = Value + self.TokenValue = Token + self.MaxDatumSize = MaxDatumSize + self.SkuInfoList = SkuInfoList + self.IsOverrided = IsOverrided + self.Phase = "DXE" + + ## Convert the class to a string + # + # Convert each member of the class to string + # Organize to a signle line format string + # + # @retval Rtn Formatted String + # + def __str__(self): + Rtn = '\tTokenCName=' + str(self.TokenCName) + ', ' + \ + 'TokenSpaceGuidCName=' + str(self.TokenSpaceGuidCName) + ', ' + \ + 'Type=' + str(self.Type) + ', ' + \ + 'DatumType=' + str(self.DatumType) + ', ' + \ + 'DefaultValue=' + str(self.DefaultValue) + ', ' + \ + 'TokenValue=' + str(self.TokenValue) + ', ' + \ + 'MaxDatumSize=' + str(self.MaxDatumSize) + ', ' + for Item in self.SkuInfoList.values(): + Rtn = Rtn + 'SkuId=' + Item.SkuId + ', ' + 'SkuIdName=' + Item.SkuIdName + Rtn = Rtn + str(self.IsOverrided) + + return Rtn + + ## Override __eq__ function + # + # Check whether pcds are the same + # + # @retval False The two pcds are different + # @retval True The two pcds are the same + # + def __eq__(self, Other): + return Other != None and self.TokenCName == Other.TokenCName and self.TokenSpaceGuidCName == Other.TokenSpaceGuidCName + + ## Override __hash__ function + # + # Use (TokenCName, TokenSpaceGuidCName) as key in hash table + # + # @retval truple() Key for hash table + # + def __hash__(self): + return hash((self.TokenCName, self.TokenSpaceGuidCName)) + +## LibraryClassObject +# +# This Class defines LibraryClassObject used in BuildDatabase +# +# @param object: Inherited from object class +# @param Name: Input value for LibraryClassName, default is None +# @param SupModList: Input value for SupModList, default is [] +# @param Type: Input value for Type, default is None +# +# @var LibraryClass: To store value for LibraryClass +# @var SupModList: To store value for SupModList +# @var Type: To store value for Type +# +class LibraryClassObject(object): + def __init__(self, Name = None, SupModList = [], Type = None): + self.LibraryClass = Name + self.SupModList = SupModList + if Type != None: + self.SupModList = CleanString(Type).split(DataType.TAB_SPACE_SPLIT) + +## ModuleBuildClassObject +# +# This Class defines ModuleBuildClass +# +# @param object: Inherited from object class +# +# @var DescFilePath: To store value for DescFilePath +# @var BaseName: To store value for BaseName +# @var ModuleType: To store value for ModuleType +# @var Guid: To store value for Guid +# @var Version: To store value for Version +# @var PcdIsDriver: To store value for PcdIsDriver +# @var BinaryModule: To store value for BinaryModule +# @var CustomMakefile: To store value for CustomMakefile +# @var Specification: To store value for Specification +# @var Shadow To store value for Shadow +# @var LibraryClass: To store value for LibraryClass, it is a list structure as +# [ LibraryClassObject, ...] +# @var ModuleEntryPointList: To store value for ModuleEntryPointList +# @var ModuleUnloadImageList: To store value for ModuleUnloadImageList +# @var ConstructorList: To store value for ConstructorList +# @var DestructorList: To store value for DestructorList +# @var Binaries: To store value for Binaries, it is a list structure as +# [ ModuleBinaryClassObject, ...] +# @var Sources: To store value for Sources, it is a list structure as +# [ ModuleSourceFilesClassObject, ... ] +# @var LibraryClasses: To store value for LibraryClasses, it is a set structure as +# { [LibraryClassName, ModuleType] : LibraryClassInfFile } +# @var Protocols: To store value for Protocols, it is a list structure as +# [ ProtocolName, ... ] +# @var Ppis: To store value for Ppis, it is a list structure as +# [ PpiName, ... ] +# @var Guids: To store value for Guids, it is a list structure as +# [ GuidName, ... ] +# @var Includes: To store value for Includes, it is a list structure as +# [ IncludePath, ... ] +# @var Packages: To store value for Packages, it is a list structure as +# [ DecFileName, ... ] +# @var Pcds: To store value for Pcds, it is a set structure as +# { [(PcdCName, PcdGuidCName)] : PcdClassObject} +# @var BuildOptions: To store value for BuildOptions, it is a set structure as +# { [BuildOptionKey] : BuildOptionValue} +# @var Depex: To store value for Depex +# +class ModuleBuildClassObject(object): + def __init__(self): + self.AutoGenVersion = 0 + self.DescFilePath = '' + self.BaseName = '' + self.ModuleType = '' + self.Guid = '' + self.Version = '' + self.PcdIsDriver = '' + self.BinaryModule = '' + self.Shadow = '' + self.CustomMakefile = {} + self.Specification = {} + self.LibraryClass = [] + self.ModuleEntryPointList = [] + self.ModuleUnloadImageList = [] + self.ConstructorList = [] + self.DestructorList = [] + + self.Binaries = [] + self.Sources = [] + self.LibraryClasses = sdict() + self.Libraries = [] + self.Protocols = [] + self.Ppis = [] + self.Guids = [] + self.Includes = [] + self.Packages = [] + self.Pcds = {} + self.BuildOptions = {} + self.Depex = '' + + ## Convert the class to a string + # + # Convert member DescFilePath of the class to a string + # + # @retval string Formatted String + # + def __str__(self): + return self.DescFilePath + + ## Override __eq__ function + # + # Check whether ModuleBuildClassObjects are the same + # + # @retval False The two ModuleBuildClassObjects are different + # @retval True The two ModuleBuildClassObjects are the same + # + def __eq__(self, Other): + return self.DescFilePath == str(Other) + + ## Override __hash__ function + # + # Use DescFilePath as key in hash table + # + # @retval string Key for hash table + # + def __hash__(self): + return hash(self.DescFilePath) + +## PackageBuildClassObject +# +# This Class defines PackageBuildClass +# +# @param object: Inherited from object class +# +# @var DescFilePath: To store value for DescFilePath +# @var PackageName: To store value for PackageName +# @var Guid: To store value for Guid +# @var Version: To store value for Version +# @var Protocols: To store value for Protocols, it is a set structure as +# { [ProtocolName] : Protocol Guid, ... } +# @var Ppis: To store value for Ppis, it is a set structure as +# { [PpiName] : Ppi Guid, ... } +# @var Guids: To store value for Guids, it is a set structure as +# { [GuidName] : Guid, ... } +# @var Includes: To store value for Includes, it is a list structure as +# [ IncludePath, ... ] +# @var LibraryClasses: To store value for LibraryClasses, it is a set structure as +# { [LibraryClassName] : LibraryClassInfFile } +# @var Pcds: To store value for Pcds, it is a set structure as +# { [(PcdCName, PcdGuidCName)] : PcdClassObject} +# +class PackageBuildClassObject(object): + def __init__(self): + self.DescFilePath = '' + self.PackageName = '' + self.Guid = '' + self.Version = '' + + self.Protocols = {} + self.Ppis = {} + self.Guids = {} + self.Includes = [] + self.LibraryClasses = {} + self.Pcds = {} + + ## Convert the class to a string + # + # Convert member DescFilePath of the class to a string + # + # @retval string Formatted String + # + def __str__(self): + return self.DescFilePath + + ## Override __eq__ function + # + # Check whether PackageBuildClassObjects are the same + # + # @retval False The two PackageBuildClassObjects are different + # @retval True The two PackageBuildClassObjects are the same + # + def __eq__(self, Other): + return self.DescFilePath == str(Other) + + ## Override __hash__ function + # + # Use DescFilePath as key in hash table + # + # @retval string Key for hash table + # + def __hash__(self): + return hash(self.DescFilePath) + +## PlatformBuildClassObject +# +# This Class defines PlatformBuildClass +# +# @param object: Inherited from object class +# +# @var DescFilePath: To store value for DescFilePath +# @var PlatformName: To store value for PlatformName +# @var Guid: To store value for Guid +# @var Version: To store value for Version +# @var DscSpecification: To store value for DscSpecification +# @var OutputDirectory: To store value for OutputDirectory +# @var FlashDefinition: To store value for FlashDefinition +# @var BuildNumber: To store value for BuildNumber +# @var MakefileName: To store value for MakefileName +# @var SkuIds: To store value for SkuIds, it is a set structure as +# { 'SkuName' : SkuId, '!include' : includefilename, ...} +# @var Modules: To store value for Modules, it is a list structure as +# [ InfFileName, ... ] +# @var Libraries: To store value for Libraries, it is a list structure as +# [ InfFileName, ... ] +# @var LibraryClasses: To store value for LibraryClasses, it is a set structure as +# { (LibraryClassName, ModuleType) : LibraryClassInfFile } +# @var Pcds: To store value for Pcds, it is a set structure as +# { [(PcdCName, PcdGuidCName)] : PcdClassObject } +# @var BuildOptions: To store value for BuildOptions, it is a set structure as +# { [BuildOptionKey] : BuildOptionValue } +# +class PlatformBuildClassObject(object): + def __init__(self): + self.DescFilePath = '' + self.PlatformName = '' + self.Guid = '' + self.Version = '' + self.DscSpecification = '' + self.OutputDirectory = '' + self.FlashDefinition = '' + self.BuildNumber = '' + self.MakefileName = '' + + self.SkuIds = {} + self.Modules = [] + self.LibraryInstances = [] + self.LibraryClasses = {} + self.Libraries = {} + self.Pcds = {} + self.BuildOptions = {} + + ## Convert the class to a string + # + # Convert member DescFilePath of the class to a string + # + # @retval string Formatted String + # + def __str__(self): + return self.DescFilePath + + ## Override __eq__ function + # + # Check whether PlatformBuildClassObjects are the same + # + # @retval False The two PlatformBuildClassObjects are different + # @retval True The two PlatformBuildClassObjects are the same + # + def __eq__(self, other): + return self.DescFilePath == str(other) + + ## Override __hash__ function + # + # Use DescFilePath as key in hash table + # + # @retval string Key for hash table + # + def __hash__(self): + return hash(self.DescFilePath) + +## ItemBuild +# +# This Class defines Module/Platform/Package databases for build system +# +# @param object: Inherited from object class +# @param Arch: Build arch +# @param Platform: Build Platform +# @param Package: Build Package +# @param Module: Build Module +# +# @var Arch: To store value for Build Arch +# @var PlatformDatabase: To store value for PlatformDatabase, it is a set structure as +# { [DscFileName] : PlatformBuildClassObject, ...} +# @var PackageDatabase: To store value for PackageDatabase, it is a set structure as +# { [DecFileName] : PacakgeBuildClassObject, ...} +# @var ModuleDatabase: To store value for ModuleDatabase, it is a list structure as +# { [InfFileName] : ModuleBuildClassObject, ...} +# +class ItemBuild(object): + def __init__(self, Arch, Platform = None, Package = None, Module = None): + self.Arch = Arch + self.PlatformDatabase = {} + self.PackageDatabase = {} + self.ModuleDatabase = {} + +## WorkspaceBuild +# +# This class is used to parse active platform to init all inf/dec/dsc files +# Generate module/package/platform databases for build +# +# @param object: Inherited from object class +# @param ActivePlatform: Input value for current active platform +# @param WorkspaceDir: Input value for current WorkspaceDir +# +# @var WorkspaceDir: To store value for WorkspaceDir +# @var SupArchList: To store value for SupArchList, selection scope is in below list +# EBC | IA32 | X64 | IPF | ARM | PPC +# @var BuildTarget: To store value for WorkspaceDir, selection scope is in below list +# RELEASE | DEBUG +# @var SkuId: To store value for SkuId +# @var Fdf: To store value for Fdf +# @var FdTargetList: To store value for FdTargetList +# @var FvTargetList: To store value for FvTargetList +# @var TargetTxt: To store value for TargetTxt, it is a set structure as +# TargetTxtClassObject +# @var ToolDef: To store value for ToolDef, it is a set structure as +# ToolDefClassObject +# @var InfDatabase: To store value for InfDatabase, it is a set structure as +# { [InfFileName] : InfClassObject} +# @var DecDatabase: To store value for DecDatabase, it is a set structure as +# { [DecFileName] : DecClassObject} +# @var DscDatabase: To store value for DscDatabase, it is a set structure as +# { [DscFileName] : DscClassObject} +# @var Build: To store value for DscDatabase, it is a set structure as +# ItemBuild +# @var DscFileName: To store value for Active Platform +# @var UnFoundPcdInDsc: To store values for the pcds defined in INF/DEC but not found in DSC, it is a set structure as +# { (PcdGuid, PcdCName, Arch) : DecFileName } +# +class WorkspaceBuild(object): + def __init__(self, ActivePlatform, WorkspaceDir): + self.WorkspaceDir = NormPath(WorkspaceDir) + self.SupArchList = [] + self.BuildTarget = [] + self.SkuId = '' + self.Fdf = '' + self.FdTargetList = [] + self.FvTargetList = [] + self.TargetTxt = None + self.ToolDef = None + + self.InfDatabase = {} + self.DecDatabase = {} + self.DscDatabase = {} + + self.UnFoundPcdInDsc = {} + + # + # Init build for all arches + # + self.Build = {} + for Arch in DataType.ARCH_LIST: + self.Build[Arch] = ItemBuild(Arch) + + # + # Init build database + # + self.Db = Database.Database(DATABASE_PATH) + self.Db.InitDatabase() + + # + # Get active platform + # + self.DscFileName = NormPath(ActivePlatform) + File = self.WorkspaceFile(self.DscFileName) + if os.path.exists(File) and os.path.isfile(File): + self.DscDatabase[self.DscFileName] = Dsc(File, False, True, self.WorkspaceDir, self.Db) + else: + EdkLogger.error("AutoGen", FILE_NOT_FOUND, ExtraData = File) + + # + # Parse platform to get module + # + for DscFile in self.DscDatabase.keys(): + Platform = self.DscDatabase[DscFile].Platform + + # + # Get global information + # + Tmp = set() + for Arch in DataType.ARCH_LIST: + for Item in Platform.Header[Arch].SupArchList: + Tmp.add(Item) + self.SupArchList = list(Tmp) + Tmp = set() + for Arch in DataType.ARCH_LIST: + for Item in Platform.Header[Arch].BuildTargets: + Tmp.add(Item) + self.BuildTarget = list(Tmp) + for Arch in self.SupArchList: + self.SkuId = Platform.Header[Arch].SkuIdName + self.Fdf = Platform.FlashDefinitionFile.FilePath + + # + # Get all inf files + # + for Item in Platform.LibraryClasses.LibraryList: + for Arch in Item.SupArchList: + self.AddToInfDatabase(Item.FilePath) + + for Item in Platform.Libraries.LibraryList: + for Arch in Item.SupArchList: + self.AddToInfDatabase(Item.FilePath) + + for Item in Platform.Modules.ModuleList: + for Arch in Item.SupArchList: + # + # Add modules + # + Module = Item.FilePath + self.AddToInfDatabase(Module) + # + # Add library used in modules + # + for Lib in Item.LibraryClasses.LibraryList: + self.AddToInfDatabase(Lib.FilePath) + self.UpdateLibraryClassOfModule(Module, Lib.Name, Arch, Lib.FilePath) + + # + # Parse module to get package + # + for InfFile in self.InfDatabase.keys(): + Module = self.InfDatabase[InfFile].Module + # + # Get all dec + # + for Item in Module.PackageDependencies: + for Arch in Item.SupArchList: + self.AddToDecDatabase(Item.FilePath) + # End of self.Init() + + ## Generate PlatformDatabase + # + # Go through each arch to get all items in DscDatabase to PlatformDatabase + # + def GenPlatformDatabase(self, PcdsSet={}): + for Dsc in self.DscDatabase.keys(): + Platform = self.DscDatabase[Dsc].Platform + for Arch in self.SupArchList: + Pb = PlatformBuildClassObject() + + # + # Defines + # + Pb.DescFilePath = Dsc + Pb.PlatformName = Platform.Header[Arch].Name + if Pb.PlatformName == '': + EdkLogger.error("AutoGen", PARSER_ERROR, "The BaseName of platform %s is not defined for arch %s" % (Dsc, Arch)) + Pb.Guid = Platform.Header[Arch].Guid + Pb.Version = Platform.Header[Arch].Version + Pb.DscSpecification = Platform.Header[Arch].DscSpecification + Pb.OutputDirectory = Platform.Header[Arch].OutputDirectory + Pb.FlashDefinition = Platform.FlashDefinitionFile.FilePath + Pb.BuildNumber = Platform.Header[Arch].BuildNumber + + # + # SkuId + # + for Key in Platform.SkuInfos.SkuInfoList.keys(): + Pb.SkuIds[Key] = Platform.SkuInfos.SkuInfoList[Key] + + # + # Module + # + for Item in Platform.Modules.ModuleList: + if Arch in Item.SupArchList: + Pb.Modules.append(Item.FilePath) + + # + # BuildOptions + # + for Item in Platform.BuildOptions.BuildOptionList: + if Arch in Item.SupArchList: + Pb.BuildOptions[(Item.ToolChainFamily, Item.ToolChain)] = Item.Option + + # + # LibraryClass + # + for Item in Platform.LibraryClasses.LibraryList: + SupModuleList = self.FindSupModuleListOfLibraryClass(Item, Platform.LibraryClasses.LibraryList, Arch) + if Arch in Item.SupArchList: + for ModuleType in SupModuleList: + Pb.LibraryClasses[(Item.Name, ModuleType)] = Item.FilePath + + # + # Libraries + # + for Item in Platform.Libraries.LibraryList: + for ItemArch in Item.SupArchList: + Library = self.InfDatabase[Item.FilePath] + if ItemArch not in Library.Module.Header: + continue + Pb.Libraries[Library.Module.Header[ItemArch].Name] = Item.FilePath + + # + # Pcds + # + for Item in Platform.DynamicPcdBuildDefinitions: + if Arch in Item.SupArchList: + Name = Item.CName + Guid = Item.TokenSpaceGuidCName + Type = Item.ItemType + DatumType = Item.DatumType + Value = Item.DefaultValue + Token = Item.Token + MaxDatumSize = Item.MaxDatumSize + SkuInfoList = Item.SkuInfoList + Pb.Pcds[(Name, Guid)] = PcdClassObject(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList, False) + + for (Name, Guid) in PcdsSet: + Value = PcdsSet[Name, Guid] + for PcdType in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]: + for Dec in self.Build[Arch].PackageDatabase: + Pcds = self.Build[Arch].PackageDatabase[Dec].Pcds + if (Name, Guid, PcdType) in Pcds: + Pcd = Pcds[(Name, Guid, PcdType)] + Type = PcdType + DatumType = Pcd.DatumType + Token = Pcd.TokenValue + MaxDatumSize = Pcd.MaxDatumSize + SkuInfoList = Pcd.SkuInfoList + Pb.Pcds[(Name, Guid)] = PcdClassObject(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList, False) + break + else: + # nothing found + continue + # found in one package, find next PCD + break + else: + EdkLogger.error("AutoGen", PARSER_ERROR, "PCD is not found in any package", ExtraData="%s.%s" % (Guid, Name)) + # + # Add to database + # + self.Build[Arch].PlatformDatabase[Dsc] = Pb + Pb = None + + ## Generate PackageDatabase + # + # Go through each arch to get all items in DecDatabase to PackageDatabase + # + def GenPackageDatabase(self): + for Dec in self.DecDatabase.keys(): + Package = self.DecDatabase[Dec].Package + + for Arch in self.SupArchList: + Pb = PackageBuildClassObject() + + # + # Defines + # + Pb.DescFilePath = Dec + Pb.PackageName = Package.Header[Arch].Name + if Pb.PackageName == '': + EdkLogger.error("AutoGen", PARSER_ERROR, "The BaseName of package %s is not defined for arch %s" % (Dec, Arch)) + + Pb.Guid = Package.Header[Arch].Guid + Pb.Version = Package.Header[Arch].Version + + # + # Protocols + # + for Item in Package.ProtocolDeclarations: + if Arch in Item.SupArchList: + Pb.Protocols[Item.CName] = Item.Guid + + # + # Ppis + # + for Item in Package.PpiDeclarations: + if Arch in Item.SupArchList: + Pb.Ppis[Item.CName] = Item.Guid + + # + # Guids + # + for Item in Package.GuidDeclarations: + if Arch in Item.SupArchList: + Pb.Guids[Item.CName] = Item.Guid + + # + # Includes + # + for Item in Package.Includes: + if Arch in Item.SupArchList: + Pb.Includes.append(Item.FilePath) + + # + # LibraryClasses + # + for Item in Package.LibraryClassDeclarations: + if Arch in Item.SupArchList: + Pb.LibraryClasses[Item.LibraryClass] = Item.RecommendedInstance + + # + # Pcds + # + for Item in Package.PcdDeclarations: + if Arch in Item.SupArchList: + Name = Item.CName + Guid = Item.TokenSpaceGuidCName + Type = Item.ItemType + DatumType = Item.DatumType + Value = Item.DefaultValue + Token = Item.Token + MaxDatumSize = Item.MaxDatumSize + SkuInfoList = Item.SkuInfoList + Pb.Pcds[(Name, Guid, Type)] = PcdClassObject(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList, False) + + # + # Add to database + # + self.Build[Arch].PackageDatabase[Dec] = Pb + Pb = None + + ## Generate ModuleDatabase + # + # Go through each arch to get all items in InfDatabase to ModuleDatabase + # + def GenModuleDatabase(self, InfList = []): + for Inf in self.InfDatabase.keys(): + Module = self.InfDatabase[Inf].Module + + for Arch in self.SupArchList: + if not self.IsModuleDefinedInPlatform(Inf, Arch, InfList) or Arch not in Module.Header: + continue + + ModuleHeader = Module.Header[Arch] + Pb = ModuleBuildClassObject() + + # + # Defines + # + Pb.DescFilePath = Inf + Pb.BaseName = ModuleHeader.Name + if Pb.BaseName == '': + EdkLogger.error("AutoGen", PARSER_ERROR, "The BaseName of module %s is not defined for arch %s" % (Inf, Arch)) + Pb.Guid = ModuleHeader.Guid + Pb.Version = ModuleHeader.Version + Pb.ModuleType = ModuleHeader.ModuleType + Pb.PcdIsDriver = ModuleHeader.PcdIsDriver + Pb.BinaryModule = ModuleHeader.BinaryModule + Pb.CustomMakefile = ModuleHeader.CustomMakefile + Pb.Shadow = ModuleHeader.Shadow + + # + # Specs os Defines + # + Pb.Specification = ModuleHeader.Specification + Pb.Specification[TAB_INF_DEFINES_EDK_RELEASE_VERSION] = ModuleHeader.EdkReleaseVersion + Pb.Specification[TAB_INF_DEFINES_EFI_SPECIFICATION_VERSION] = ModuleHeader.EfiSpecificationVersion + Pb.AutoGenVersion = int(ModuleHeader.InfVersion, 0) + + # + # LibraryClass of Defines + # + for Item in ModuleHeader.LibraryClass: + Pb.LibraryClass.append(LibraryClassObject(Item.LibraryClass, Item.SupModuleList, None)) + + # + # Module image and library of Defines + # + for Item in Module.ExternImages: + if Item.ModuleEntryPoint != '' and Item.ModuleEntryPoint not in Pb.ModuleEntryPointList: + Pb.ModuleEntryPointList.append(Item.ModuleEntryPoint) + if Item.ModuleUnloadImage != '' and Item.ModuleUnloadImage not in Pb.ModuleUnloadImageList: + Pb.ModuleUnloadImageList.append(Item.ModuleUnloadImage) + for Item in Module.ExternLibraries: + if Item.Constructor != '' and Item.Constructor not in Pb.ConstructorList: + Pb.ConstructorList.append(Item.Constructor) + if Item.Destructor != '' and Item.Destructor not in Pb.DestructorList: + Pb.DestructorList.append(Item.Destructor) + + # + # Binaries + # + for Item in Module.Binaries: + if Arch in Item.SupArchList: + FileName = Item.BinaryFile + FileType = Item.FileType + Target = Item.Target + FeatureFlag = Item.FeatureFlag + Pb.Binaries.append(ModuleBinaryFileClass(FileName, FileType, Target, FeatureFlag, Arch.split())) + + # + # Sources + # + for Item in Module.Sources: + if Arch in Item.SupArchList: + SourceFile = Item.SourceFile + TagName = Item.TagName + ToolCode = Item.ToolCode + ToolChainFamily = Item.ToolChainFamily + FeatureFlag = Item.FeatureFlag + Pb.Sources.append(ModuleSourceFileClass(SourceFile, TagName, ToolCode, ToolChainFamily, FeatureFlag)) + + # + # Protocols + # + for Item in Module.Protocols: + if Arch in Item.SupArchList: + Pb.Protocols.append(Item.CName) + + # + # Ppis + # + for Item in Module.Ppis: + if Arch in Item.SupArchList: + Pb.Ppis.append(Item.CName) + + # + # Guids + # + for Item in Module.Guids: + if Arch in Item.SupArchList: + Pb.Ppis.append(Item.CName) + + # + # Includes + # + for Item in Module.Includes: + if Arch in Item.SupArchList: + Pb.Includes.append(Item.FilePath) + + # + # Packages + # + for Item in Module.PackageDependencies: + if Arch in Item.SupArchList: + Pb.Packages.append(Item.FilePath) + + # + # BuildOptions + # + for Item in Module.BuildOptions: + if Arch in Item.SupArchList: + if (Item.ToolChainFamily, Item.ToolChain) not in Pb.BuildOptions: + Pb.BuildOptions[(Item.ToolChainFamily, Item.ToolChain)] = Item.Option + else: + OptionString = Pb.BuildOptions[(Item.ToolChainFamily, Item.ToolChain)] + Pb.BuildOptions[(Item.ToolChainFamily, Item.ToolChain)] = OptionString + " " + Item.Option + self.FindBuildOptions(Arch, Inf, Pb.BuildOptions) + + # + # Depex + # + for Item in Module.Depex: + if Arch in Item.SupArchList: + Pb.Depex = Pb.Depex + Item.Depex + ' ' + Pb.Depex = Pb.Depex.strip() + + # + # LibraryClasses + # + for Item in Module.LibraryClasses: + if Arch in Item.SupArchList: + Lib = Item.LibraryClass + RecommendedInstance = Item.RecommendedInstance + if Pb.LibraryClass != []: + # + # For Library + # + for Libs in Pb.LibraryClass: + for Type in Libs.SupModList: + Instance = self.FindLibraryClassInstanceOfLibrary(Lib, Arch, Type) + if Instance == None: + Instance = RecommendedInstance + Pb.LibraryClasses[(Lib, Type)] = Instance + else: + # + # For Module + # + Instance = self.FindLibraryClassInstanceOfModule(Lib, Arch, Pb.ModuleType, Inf) + if Instance == None: + Instance = RecommendedInstance + Pb.LibraryClasses[(Lib, Pb.ModuleType)] = Instance + + # + # Libraries + # + for Item in Module.Libraries: + if Arch in Item.SupArchList: + Pb.Libraries.append(Item.Library) + + # + # Pcds + # + for Item in Module.PcdCodes: + if Arch in Item.SupArchList: + Name = Item.CName + Guid = Item.TokenSpaceGuidCName + Type = Item.ItemType + Pb.Pcds[(Name, Guid)] = self.FindPcd(Arch, Inf, Name, Guid, Type) + + # + # Add to database + # + self.Build[Arch].ModuleDatabase[Inf] = Pb + Pb = None + + ## Update Libraries Of Platform Database + # + # @param InfList: A list for all inf files + # + def UpdateLibrariesOfPlatform(self, InfList = []): + for Arch in self.SupArchList: + PlatformDatabase = self.Build[Arch].PlatformDatabase + for Dsc in PlatformDatabase: + Platform = PlatformDatabase[Dsc] + for Inf in Platform.Modules: + if not self.IsModuleDefinedInPlatform(Inf, Arch, InfList): + continue + Module = self.Build[Arch].ModuleDatabase[Inf] + if Module.LibraryClass == None or Module.LibraryClass == []: + self.UpdateLibrariesOfModule(Platform, Module, Arch) + for Key in Module.LibraryClasses: + Lib = Module.LibraryClasses[Key] + if Lib not in Platform.LibraryInstances: + Platform.LibraryInstances.append(Lib) + + + ## Update Libraries Of Module Database + # + # @param Module: The module need to be updated libraries + # @param Arch: The supportted arch of the module + # + def UpdateLibrariesOfModule(self, Platform, Module, Arch): + ModuleDatabase = self.Build[Arch].ModuleDatabase + ModuleType = Module.ModuleType + + # check R8 module + if Module.AutoGenVersion < 0x00010005: + EdkLogger.verbose("") + EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), Arch)) + LibraryConsumerList = [Module] + + # "CompilerStub" is a must for R8 modules + Module.Libraries.append("CompilerStub") + while len(LibraryConsumerList) > 0: + M = LibraryConsumerList.pop() + for LibraryName in M.Libraries: + if LibraryName not in Platform.Libraries: + EdkLogger.warn("AutoGen", "Library [%s] is not found" % LibraryName, + ExtraData="\t%s [%s]" % (str(Module), Arch)) + continue + + LibraryFile = Platform.Libraries[LibraryName] + if (LibraryName, ModuleType) not in Module.LibraryClasses: + Module.LibraryClasses[LibraryName, ModuleType] = LibraryFile + LibraryConsumerList.append(ModuleDatabase[LibraryFile]) + EdkLogger.verbose("\t" + LibraryName + " : " + LibraryFile) + return + + # R9 module + LibraryConsumerList = [Module] + Constructor = [] + ConsumedByList = sdict() + LibraryInstance = sdict() + + EdkLogger.verbose("") + EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), Arch)) + while len(LibraryConsumerList) > 0: + M = LibraryConsumerList.pop() + for Key, LibraryPath in M.LibraryClasses.iteritems(): + # The "Key" is in format of (library_class_name, supported_module_type) + if ModuleType != "USER_DEFINED" and ModuleType not in Key: + EdkLogger.debug(EdkLogger.DEBUG_3, "%s for module type %s is not supported (%s)" % (Key + (LibraryPath,))) + continue + + LibraryClassName = Key[0] + if LibraryClassName not in LibraryInstance or LibraryInstance[LibraryClassName] == None: + if LibraryPath == None or LibraryPath == "": + LibraryInstance[LibraryClassName] = None + continue + LibraryModule = ModuleDatabase[LibraryPath] + LibraryInstance[LibraryClassName] = LibraryModule + LibraryConsumerList.append(LibraryModule) + EdkLogger.verbose("\t" + LibraryClassName + " : " + str(LibraryModule)) + elif LibraryPath == None or LibraryPath == "": + continue + else: + LibraryModule = LibraryInstance[LibraryClassName] + + if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor: + Constructor.append(LibraryModule) + + if LibraryModule not in ConsumedByList: + ConsumedByList[LibraryModule] = [] + if M != Module: + if M in ConsumedByList[LibraryModule]: + continue + ConsumedByList[LibraryModule].append(M) + # + # Initialize the sorted output list to the empty set + # + SortedLibraryList = [] + # + # Q <- Set of all nodes with no incoming edges + # + LibraryList = [] #LibraryInstance.values() + Q = [] + for LibraryClassName in LibraryInstance: + M = LibraryInstance[LibraryClassName] + if M == None: + EdkLogger.error("AutoGen", AUTOGEN_ERROR, + "Library instance for library class [%s] is not found" % LibraryClassName, + ExtraData="\t%s [%s]" % (str(Module), Arch)) + LibraryList.append(M) + # + # check if there're duplicate library classes + # + for Lc in M.LibraryClass: + if Lc.SupModList != None and ModuleType not in Lc.SupModList: + EdkLogger.error("AutoGen", AUTOGEN_ERROR, + "Module type [%s] is not supported by library instance [%s]" % (ModuleType, str(M)), + ExtraData="\t%s" % str(Module)) + + if Lc.LibraryClass in LibraryInstance and str(M) != str(LibraryInstance[Lc.LibraryClass]): + EdkLogger.error("AutoGen", AUTOGEN_ERROR, + "More than one library instance found for library class [%s] in module [%s]" % (Lc.LibraryClass, Module), + ExtraData="\t%s\n\t%s" % (LibraryInstance[Lc.LibraryClass], str(M)) + ) + if ConsumedByList[M] == []: + Q.insert(0, M) + # + # while Q is not empty do + # + while Q != []: + # + # remove node from Q + # + Node = Q.pop() + # + # output Node + # + SortedLibraryList.append(Node) + # + # for each node Item with an edge e from Node to Item do + # + for Item in LibraryList: + if Node not in ConsumedByList[Item]: + continue + # + # remove edge e from the graph + # + ConsumedByList[Item].remove(Node) + # + # If Item has no other incoming edges then + # + if ConsumedByList[Item] == []: + # + # insert Item into Q + # + Q.insert(0, Item) + + EdgeRemoved = True + while Q == [] and EdgeRemoved: + EdgeRemoved = False + # + # for each node Item with a Constructor + # + for Item in LibraryList: + if Item in Constructor: + # + # for each Node without a constructor with an edge e from Item to Node + # + for Node in ConsumedByList[Item]: + if Node not in Constructor: + # + # remove edge e from the graph + # + ConsumedByList[Item].remove(Node) + EdgeRemoved = True + if ConsumedByList[Item] == []: + # + # insert Item into Q + # + Q.insert(0, Item) + break + if Q != []: + break + + # + # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle + # + for Item in LibraryList: + if ConsumedByList[Item] != [] and Item in Constructor and len(Constructor) > 1: + ErrorMessage = 'Library [%s] with constructors has a cycle' % str(Item) + EdkLogger.error("AutoGen", AUTOGEN_ERROR, ErrorMessage, + "\tconsumed by " + "\n\tconsumed by ".join([str(L) for L in ConsumedByList[Item]])) + if Item not in SortedLibraryList: + SortedLibraryList.append(Item) + + # + # Build the list of constructor and destructir names + # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order + # + SortedLibraryList.reverse() + Module.LibraryClasses = sdict() + for L in SortedLibraryList: + for Lc in L.LibraryClass: + Module.LibraryClasses[Lc.LibraryClass, ModuleType] = str(L) + # + # Merge PCDs from library instance + # + for Key in L.Pcds: + if Key not in Module.Pcds: + LibPcd = L.Pcds[Key] + Module.Pcds[Key] = self.FindPcd(Arch, str(Module), LibPcd.TokenCName, LibPcd.TokenSpaceGuidCName, LibPcd.Type) + # + # Merge GUIDs from library instance + # + for CName in L.Guids: + if CName not in Module.Guids: + Module.Guids.append(CName) + # + # Merge Protocols from library instance + # + for CName in L.Protocols: + if CName not in Module.Protocols: + Module.Protocols.append(CName) + # + # Merge Ppis from library instance + # + for CName in L.Ppis: + if CName not in Module.Ppis: + Module.Ppis.append(CName) + + ## GenBuildDatabase + # + # Generate build database for all arches + # + # @param PcdsSet: Pcd list for override from Fdf parse result + # @param InfList: Inf list for override from Fdf parse result + # + def GenBuildDatabase(self, PcdsSet = {}, InfList = []): + # + # Add additional inf file defined in Fdf file + # + for InfFile in InfList: + self.AddToInfDatabase(NormPath(InfFile)) + + # + # Generate PlatformDatabase, PackageDatabase and ModuleDatabase + # + self.GenPackageDatabase() + self.GenPlatformDatabase(PcdsSet) + self.GenModuleDatabase(InfList) + + self.Db.Close() + + # + # Update Libraries Of Platform + # + self.UpdateLibrariesOfPlatform(InfList) + + # + # Output used Pcds not found in DSC file + # + self.ShowUnFoundPcds() + + ## ShowUnFoundPcds() + # + # If there is any pcd used but not defined in DSC + # Print warning message on screen and output a list of pcds + # + def ShowUnFoundPcds(self): + if self.UnFoundPcdInDsc != {}: + WrnMessage = '**** WARNING ****\n' + WrnMessage += 'The following Pcds were not defined in the DSC file: %s\n' % self.DscFileName + WrnMessage += 'The default values were obtained from the DEC file that declares the PCD and the PCD default value\n' + for (Guid, Name, Type, Arch) in self.UnFoundPcdInDsc: + Dec = self.UnFoundPcdInDsc[(Guid, Name, Type, Arch)] + Pcds = self.Build[Arch].PackageDatabase[Dec].Pcds + if (Name, Guid, Type) in Pcds: + Pcd = Pcds[(Name, Guid, Type)] + PcdItemTypeUsed = Pcd.Type + DefaultValue = Pcd.DefaultValue + WrnMessage += '%s.%s: Defined in file %s, PcdItemType is Pcds%s, DefaultValue is %s\n' % (Guid, Name, Dec, PcdItemTypeUsed, DefaultValue) + EdkLogger.verbose(WrnMessage) + + ## Create a full path with workspace dir + # + # Convert Filename with workspace dir to create a full path + # + # @param Filename: The filename need to be added workspace dir + # + # @retval string Full path + # + def WorkspaceFile(self, Filename): + return WorkspaceFile(self.WorkspaceDir, Filename) + + ## Update LibraryClass of Module + # + # If a module of a platform has its own override libraryclass but the libraryclass not defined in the module + # Add this libraryclass to the module + # + # @param InfFileName: InfFileName specificed in platform + # @param LibraryClass: LibraryClass specificed in platform + # @param Arch: Supportted Arch + # @param InstanceFilePath: InstanceFilePath specificed in platform + # + def UpdateLibraryClassOfModule(self, InfFileName, LibraryClass, Arch, InstanceFilePath): + # + # Update the library instance itself to add this libraryclass name + # + LibraryModule = self.InfDatabase[InstanceFilePath].Module + LibList = LibraryModule.Header[Arch].LibraryClass + NotFound = True + for Lib in LibList: + # + # Find this LibraryClass + # + if Lib.LibraryClass == LibraryClass: + NotFound = False; + break; + if NotFound: + NewLib = LibraryClassClass() + NewLib.LibraryClass = LibraryClass + NewLib.SupModuleList = DataType.SUP_MODULE_LIST # LibraryModule.Header[Arch].ModuleType.split() + LibraryModule.Header[Arch].LibraryClass.append(NewLib) + + # + # Add it to LibraryClasses Section for the module which is using the library + # + Module = self.InfDatabase[InfFileName].Module + LibList = Module.LibraryClasses + NotFound = True + for Lib in LibList: + # + # Find this LibraryClass + # + if Lib.LibraryClass == LibraryClass: + if Arch in Lib.SupArchList: + return + else: + Lib.SupArchList.append(Arch) + return + if NotFound: + Lib = LibraryClassClass() + Lib.LibraryClass = LibraryClass + Lib.SupArchList = [Arch] + Module.LibraryClasses.append(Lib) + + ## Add Inf file to InfDatabase + # + # Create a Inf instance for input inf file and add it to InfDatabase + # + # @param InfFileName: The InfFileName need to be added to database + # + def AddToInfDatabase(self, InfFileName): + File = self.WorkspaceFile(InfFileName) + if os.path.exists(File) and os.path.isfile(File): + if InfFileName not in self.InfDatabase: + self.InfDatabase[InfFileName] = Inf(File, False, True, self.WorkspaceDir, self.Db, self.SupArchList) + else: + EdkLogger.error("AutoGen", FILE_NOT_FOUND, ExtraData=File) + + ## Add Dec file to DecDatabase + # + # Create a Dec instance for input dec file and add it to DecDatabase + # + # @param DecFileName: The DecFileName need to be added to database + # + def AddToDecDatabase(self, DecFileName): + File = self.WorkspaceFile(DecFileName) + if os.path.exists(File) and os.path.isfile(File): + if DecFileName not in self.DecDatabase: + self.DecDatabase[DecFileName] = Dec(File, False, True, self.WorkspaceDir, self.Db, self.SupArchList) + else: + EdkLogger.error("AutoGen", FILE_NOT_FOUND, ExtraData=File) + + ## Search LibraryClass Instance for Module + # + # Search PlatformBuildDatabase to find LibraryClass Instance for Module + # Return the instance if found + # + # @param Lib: Input value for Library Class Name + # @param Arch: Supportted Arch + # @param ModuleType: Supportted ModuleType + # @param ModuleName: Input value for Module Name + # + # @retval string Found LibraryClass Instance file path + # + def FindLibraryClassInstanceOfModule(self, Lib, Arch, ModuleType, ModuleName): + # + # First find if exist in of from dsc file + # + for Dsc in self.DscDatabase.keys(): + Platform = self.DscDatabase[Dsc].Platform + for Module in Platform.Modules.ModuleList: + if Arch in Module.SupArchList: + if Module.FilePath == ModuleName: + for LibraryClass in Module.LibraryClasses.LibraryList: + if LibraryClass.Name == Lib: + return LibraryClass.FilePath + # + #Second find if exist in of from dsc file + # + return self.FindLibraryClassInstanceOfLibrary(Lib, Arch, ModuleType) + + ## Search LibraryClass Instance for Library + # + # Search PlatformBuildDatabase to find LibraryClass Instance for Library + # Return the instance if found + # + # @param Lib: Input value for Library Class Name + # @param Arch: Supportted Arch + # @param Type: Supportted Library Usage Type + # + # @retval string Found LibraryClass Instance file path + # @retval None Not Found + # + def FindLibraryClassInstanceOfLibrary(self, Lib, Arch, Type): + for Dsc in self.DscDatabase.keys(): + Platform = self.DscDatabase[Dsc].Platform + if (Lib, Type) in self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses: + return self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses[(Lib, Type)] + elif (Lib, '') in self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses: + return self.Build[Arch].PlatformDatabase[Dsc].LibraryClasses[(Lib, '')] + return None + + ## Find BuildOptions + # + # Search DscDatabase to find component definition of ModuleName + # Override BuildOption if it is defined in component + # + # @param Arch: Supportted Arch + # @param ModuleName: The module which has buildoption definition in component of platform + # @param BuildOptions: The set of all buildopitons + # + def FindBuildOptions(self, Arch, ModuleName, BuildOptions): + for Dsc in self.DscDatabase.keys(): + # + # First find if exist in of from dsc file + # if find, use that override the one defined in inf file + # + Platform = self.DscDatabase[Dsc].Platform + for Module in Platform.Modules.ModuleList: + if Arch in Module.SupArchList: + if Module.FilePath == ModuleName: + for BuildOption in Module.ModuleSaBuildOption.BuildOptionList: + # + # Add to BuildOptions + # + BuildOptions[(BuildOption.ToolChainFamily, BuildOption.ToolChain)] = BuildOption.Option + + ## Find Pcd + # + # Search platform database, package database, module database and PcdsSet from Fdf + # Return found Pcd + # + # @param Arch: Supportted Arch + # @param ModuleName: The module which has pcd definition in component of platform + # @param Name: Name of Pcd + # @param Guid: Guid of Pcd + # @param Type: Type of Pcd + # + # @retval PcdClassObject An instance for PcdClassObject with all members filled + # + def FindPcd(self, Arch, ModuleName, Name, Guid, Type): + NewType = '' + DatumType = '' + Value = '' + Token = '' + MaxDatumSize = '' + SkuInfoList = {} + IsOverrided = False + IsFoundInDsc = False + IsFoundInDec = False + FoundInDecFile = '' + + # + # Second get information from platform database + # + OwnerPlatform = '' + for Dsc in self.Build[Arch].PlatformDatabase.keys(): + Pcds = self.Build[Arch].PlatformDatabase[Dsc].Pcds + if (Name, Guid) in Pcds: + OwnerPlatform = Dsc + Pcd = Pcds[(Name, Guid)] + if Pcd.Type != '' and Pcd.Type != None: + NewType = Pcd.Type + if NewType in DataType.PCD_DYNAMIC_TYPE_LIST: + NewType = DataType.TAB_PCDS_DYNAMIC + elif NewType in DataType.PCD_DYNAMIC_EX_TYPE_LIST: + NewType = DataType.TAB_PCDS_DYNAMIC_EX + else: + NewType = Type + + if Type != '' and Type != NewType: + ErrorMsg = "PCD %s.%s is declared as [%s] in module\n\t%s\n\n"\ + " But it's used as [%s] in platform\n\t%s"\ + % (Guid, Name, Type, ModuleName, NewType, OwnerPlatform) + EdkLogger.error("AutoGen", PARSER_ERROR, ErrorMsg) + + + if Pcd.DatumType != '' and Pcd.DatumType != None: + DatumType = Pcd.DatumType + if Pcd.TokenValue != '' and Pcd.TokenValue != None: + Token = Pcd.TokenValue + if Pcd.DefaultValue != '' and Pcd.DefaultValue != None: + Value = Pcd.DefaultValue + if Pcd.MaxDatumSize != '' and Pcd.MaxDatumSize != None: + MaxDatumSize = Pcd.MaxDatumSize + SkuInfoList = Pcd.SkuInfoList + + IsOverrided = True + IsFoundInDsc = True + break + + # + # Third get information from of from module database + # + for Dsc in self.DscDatabase.keys(): + for Module in self.DscDatabase[Dsc].Platform.Modules.ModuleList: + if Arch in Module.SupArchList: + if Module.FilePath == ModuleName: + for Pcd in Module.PcdBuildDefinitions: + if (Name, Guid) == (Pcd.CName, Pcd.TokenSpaceGuidCName): + if Pcd.DefaultValue != '': + Value = Pcd.DefaultValue + if Pcd.MaxDatumSize != '': + MaxDatumSize = Pcd.MaxDatumSize + + IsFoundInDsc = True + IsOverrided = True + break + + # + # First get information from package database + # + Pcd = None + if NewType == '': + if Type != '': + PcdTypeList = [Type] + else: + PcdTypeList = ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"] + + for Dec in self.Build[Arch].PackageDatabase.keys(): + Pcds = self.Build[Arch].PackageDatabase[Dec].Pcds + for PcdType in PcdTypeList: + if (Name, Guid, PcdType) in Pcds: + Pcd = Pcds[(Name, Guid, PcdType)] + NewType = PcdType + IsOverrided = True + IsFoundInDec = True + FoundInDecFile = Dec + break + else: + continue + break + else: + for Dec in self.Build[Arch].PackageDatabase.keys(): + Pcds = self.Build[Arch].PackageDatabase[Dec].Pcds + if (Name, Guid, NewType) in Pcds: + Pcd = Pcds[(Name, Guid, NewType)] + IsOverrided = True + IsFoundInDec = True + FoundInDecFile = Dec + break + + if not IsFoundInDec: + ErrorMsg = "Pcd '%s.%s [%s]' defined in module '%s' is not found in any package for Arch '%s'" % (Guid, Name, NewType, ModuleName, Arch) + EdkLogger.error("AutoGen", PARSER_ERROR, ErrorMsg) + + # + # Not found in any platform and fdf + # + if not IsFoundInDsc: + Value = Pcd.DefaultValue + if NewType.startswith("Dynamic") and SkuInfoList == {}: + SkuIds = self.Build[Arch].PlatformDatabase.values()[0].SkuIds + SkuInfoList['DEFAULT'] = SkuInfoClass(SkuIdName='DEFAULT', SkuId=SkuIds['DEFAULT'], DefaultValue=Value) + self.UnFoundPcdInDsc[(Guid, Name, NewType, Arch)] = FoundInDecFile + #elif Type != '' and NewType.startswith("Dynamic"): + # NewType = Pcd.Type + DatumType = Pcd.DatumType + if Token in [None, '']: + Token = Pcd.TokenValue + if DatumType == "VOID*" and MaxDatumSize in ['', None]: + EdkLogger.verbose("No MaxDatumSize specified for PCD %s.%s in module [%s]" % (Guid, Name, ModuleName)) + if Value[0] == 'L': + MaxDatumSize = str(len(Value) * 2) + elif Value[0] == '{': + MaxDatumSize = str(len(Value.split(','))) + else: + MaxDatumSize = str(len(Value)) + + return PcdClassObject(Name, Guid, NewType, DatumType, Value, Token, MaxDatumSize, SkuInfoList, IsOverrided) + + ## Find Supportted Module List Of LibraryClass + # + # Search in InfDatabase, find the supmodulelist of the libraryclass + # + # @param LibraryClass: LibraryClass name for search + # @param OverridedLibraryClassList: A list of all LibraryClass + # @param Arch: Supportted Arch + # + # @retval list SupModuleList + # + def FindSupModuleListOfLibraryClass(self, LibraryClass, OverridedLibraryClassList, Arch): + Name = LibraryClass.Name + FilePath = LibraryClass.FilePath + SupModuleList = copy.copy(LibraryClass.SupModuleList) + + # + # If the SupModuleList means all, remove overrided module types of platform + # + if SupModuleList == DataType.SUP_MODULE_LIST: + EdkLogger.debug(EdkLogger.DEBUG_3, "\tLibraryClass %s supports all module types" % Name) + for Item in OverridedLibraryClassList: + # + # Find a library class (Item) with the same name + # + if Item.Name == Name: + # + # Do nothing if it is itself + # + if Item.SupModuleList == DataType.SUP_MODULE_LIST: + continue + # + # If not itself, check arch first + # + if Arch in LibraryClass.SupArchList: + # + # If arch is supportted, remove all related module type + # + if Arch in Item.SupArchList: + for ModuleType in Item.SupModuleList: + EdkLogger.debug(EdkLogger.DEBUG_3, "\tLibraryClass %s has specific defined module types" % Name) + if ModuleType in SupModuleList: + SupModuleList.remove(ModuleType) + + return SupModuleList + + ## Find Module inf Platform + # + # Check if the module is defined in of + # + # @param Inf: Inf file (Module) need to be searched + # @param Arch: Supportted Arch + # @param InfList: A list for all Inf file + # + # @retval True Mudule Found + # @retval Flase Module Not Found + # + def IsModuleDefinedInPlatform(self, Inf, Arch, InfList): + for Dsc in self.DscDatabase.values(): + for LibraryClass in Dsc.Platform.LibraryClasses.LibraryList: + if Inf == LibraryClass.FilePath and Arch in LibraryClass.SupArchList: + return True + for Module in Dsc.Platform.Modules.ModuleList: + if Inf == Module.FilePath and Arch in Module.SupArchList: + return True + for Item in Module.LibraryClasses.LibraryList: + if Inf == Item.FilePath: + return True + for Library in Dsc.Platform.Libraries.LibraryList: + if Inf == Library.FilePath and Arch in Library.SupArchList: + return True + + return False + + ## Show all content of the workspacebuild + # + # Print each item of the workspacebuild with (Key = Value) pair + # + def ShowWorkspaceBuild(self): + print self.DscDatabase + print self.InfDatabase + print self.DecDatabase + print 'SupArchList', self.SupArchList + print 'BuildTarget', self.BuildTarget + print 'SkuId', self.SkuId + + for Arch in self.SupArchList: + print Arch + print 'Platform' + for Platform in self.Build[Arch].PlatformDatabase.keys(): + P = self.Build[Arch].PlatformDatabase[Platform] + print 'DescFilePath = ', P.DescFilePath + print 'PlatformName = ', P.PlatformName + print 'Guid = ', P.Guid + print 'Version = ', P.Version + print 'OutputDirectory = ', P.OutputDirectory + print 'FlashDefinition = ', P.FlashDefinition + print 'SkuIds = ', P.SkuIds + print 'Modules = ', P.Modules + print 'LibraryClasses = ', P.LibraryClasses + print 'Pcds = ', P.Pcds + for item in P.Pcds.keys(): + print P.Pcds[item] + print 'BuildOptions = ', P.BuildOptions + print '' + # End of Platform + + print 'package' + for Package in self.Build[Arch].PackageDatabase.keys(): + P = self.Build[Arch].PackageDatabase[Package] + print 'DescFilePath = ', P.DescFilePath + print 'PackageName = ', P.PackageName + print 'Guid = ', P.Guid + print 'Version = ', P.Version + print 'Protocols = ', P.Protocols + print 'Ppis = ', P.Ppis + print 'Guids = ', P.Guids + print 'Includes = ', P.Includes + print 'LibraryClasses = ', P.LibraryClasses + print 'Pcds = ', P.Pcds + for item in P.Pcds.keys(): + print P.Pcds[item] + print '' + # End of Package + + print 'module' + for Module in self.Build[Arch].ModuleDatabase.keys(): + P = self.Build[Arch].ModuleDatabase[Module] + print 'DescFilePath = ', P.DescFilePath + print 'BaseName = ', P.BaseName + print 'ModuleType = ', P.ModuleType + print 'Guid = ', P.Guid + print 'Version = ', P.Version + print 'CustomMakefile = ', P.CustomMakefile + print 'Specification = ', P.Specification + print 'Shadow = ', P.Shadow + print 'PcdIsDriver = ', P.PcdIsDriver + for Lib in P.LibraryClass: + print 'LibraryClassDefinition = ', Lib.LibraryClass, 'SupModList = ', Lib.SupModList + print 'ModuleEntryPointList = ', P.ModuleEntryPointList + print 'ModuleUnloadImageList = ', P.ModuleUnloadImageList + print 'ConstructorList = ', P.ConstructorList + print 'DestructorList = ', P.DestructorList + + print 'Binaries = ' + for item in P.Binaries: + print item.BinaryFile, item.FeatureFlag, item.SupArchList + print 'Sources = ' + for item in P.Sources: + print item.SourceFile + print 'LibraryClasses = ', P.LibraryClasses + print 'Protocols = ', P.Protocols + print 'Ppis = ', P.Ppis + print 'Guids = ', P.Guids + print 'Includes = ', P.Includes + print 'Packages = ', P.Packages + print 'Pcds = ', P.Pcds + for item in P.Pcds.keys(): + print P.Pcds[item] + print 'BuildOptions = ', P.BuildOptions + print 'Depex = ', P.Depex + print '' + # End of Module + +## +# +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +# +if __name__ == '__main__': + print 'Start!', time.strftime('%H:%M:%S', time.localtime()) + EdkLogger.Initialize() + EdkLogger.SetLevel(EdkLogger.QUIET) + + W = os.getenv('WORKSPACE') + Ewb = WorkspaceBuild('Nt32Pkg/Nt32Pkg.dsc', W) + Ewb.GenBuildDatabase({('PcdDevicePathSupportDevicePathFromText', 'gEfiMdeModulePkgTokenSpaceGuid') : 'KKKKKKKKKKKKKKKKKKKKK'}, ['Test.Inf']) + print 'Done!', time.strftime('%H:%M:%S', time.localtime()) + Ewb.ShowWorkspaceBuild() diff --git a/BaseTools/Source/Python/Common/EdkLogger.py b/BaseTools/Source/Python/Common/EdkLogger.py new file mode 100644 index 0000000000..ce4cfa14bb --- /dev/null +++ b/BaseTools/Source/Python/Common/EdkLogger.py @@ -0,0 +1,269 @@ +## @file +# This file implements the log mechanism for Python tools. +# +# Copyright (c) 2007, 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 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 sys, os, logging +import traceback +from BuildToolError import * + +## 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 +ERROR = 50 + +IsRaiseError = True + +# Tool name +_ToolName = os.path.basename(sys.argv[0]) + +# For validation purpose +_LogLevels = [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] + +# For DEBUG level (All DEBUG_0~9 are applicable) +_DebugLogger = logging.getLogger("tool_debug") +_DebugFormatter = logging.Formatter("[%(asctime)s.%(msecs)d]: %(message)s", datefmt="%H:%M:%S") + +# For VERBOSE, INFO, WARN level +_InfoLogger = logging.getLogger("tool_info") +_InfoFormatter = logging.Formatter("%(message)s") + +# For ERROR level +_ErrorLogger = logging.getLogger("tool_error") +_ErrorFormatter = logging.Formatter("%(message)s") + +# String templates for ERROR/WARN/DEBUG log message +_ErrorMessageTemplate = '\n\n%(tool)s...\n%(file)s(%(line)s): error %(errorcode)04X: %(msg)s\n\t%(extra)s' +_ErrorMessageTemplateWithoutFile = '\n\n%(tool)s...\n : error %(errorcode)04X: %(msg)s\n\t%(extra)s' +_WarningMessageTemplate = '%(tool)s...\n%(file)s(%(line)s): warning: %(msg)s' +_WarningMessageTemplateWithoutFile = '%(tool)s: : warning: %(msg)s' +_DebugMessageTemplate = '%(file)s(%(line)s): debug: \n %(msg)s' + +# +# Flag used to take WARN as ERROR. +# By default, only ERROR message will break the tools execution. +# +_WarningAsError = False + +## 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 _DebugLogger.level > Level: + return + if Level > DEBUG_9: + return + + # Find out the caller method information + CallerStack = traceback.extract_stack()[-2] + TemplateDict = { + "file" : CallerStack[0], + "line" : CallerStack[1], + "msg" : Message, + } + + if ExtraData != None: + LogText = _DebugMessageTemplate % TemplateDict + "\n %s" % ExtraData + else: + LogText = _DebugMessageTemplate % TemplateDict + + _DebugLogger.log(Level, LogText) + +## Log verbose message +# +# @param Message Verbose information +# +def verbose(Message): + return _InfoLogger.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 _InfoLogger.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(traceback.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 = _WarningMessageTemplate % TemplateDict + else: + LogText = _WarningMessageTemplateWithoutFile % TemplateDict + + if ExtraData != None: + LogText += "\n %s" % ExtraData + + _InfoLogger.log(WARN, LogText) + + # Raise an execption if indicated + if _WarningAsError == True: + raise FatalError(WARNING_AS_ERROR) + +## Log INFO message +info = _InfoLogger.info + +## 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=IsRaiseError): + if Line == None: + Line = "..." + else: + Line = "%d" % Line + + if Message == None: + if ErrorCode in gErrorMessage: + Message = gErrorMessage[ErrorCode] + else: + Message = gErrorMessage[UNKNOWN_ERROR] + + if ExtraData == None: + ExtraData = "" + + TemplateDict = { + "tool" : _ToolName, + "file" : File, + "line" : Line, + "errorcode" : ErrorCode, + "msg" : Message, + "extra" : ExtraData + } + + if File != None: + LogText = _ErrorMessageTemplate % TemplateDict + else: + LogText = _ErrorMessageTemplateWithoutFile % TemplateDict + + _ErrorLogger.log(ERROR, LogText) + if RaiseError: + raise FatalError(ErrorCode) + +# Log information which should be always put out +quiet = _ErrorLogger.error + +## 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) + _DebugLogger.setLevel(INFO) + _DebugChannel = logging.StreamHandler(sys.stdout) + _DebugChannel.setFormatter(_DebugFormatter) + _DebugLogger.addHandler(_DebugChannel) + + # For VERBOSE, INFO, WARN level + _InfoLogger.setLevel(INFO) + _InfoChannel = logging.StreamHandler(sys.stdout) + _InfoChannel.setFormatter(_InfoFormatter) + _InfoLogger.addHandler(_InfoChannel) + + # For ERROR level + _ErrorLogger.setLevel(INFO) + _ErrorCh = logging.StreamHandler(sys.stderr) + _ErrorCh.setFormatter(_ErrorFormatter) + _ErrorLogger.addHandler(_ErrorCh) + +## Set log level +# +# @param Level One of log level in _LogLevel +def SetLevel(Level): + if Level not in _LogLevels: + info("Not supported log level (%d). Use default level instead." % Level) + Level = INFO + _DebugLogger.setLevel(Level) + _InfoLogger.setLevel(Level) + _ErrorLogger.setLevel(Level) + +## Get current log level +def GetLevel(): + return _InfoLogger.getEffectiveLevel() + +## Raise up warning as error +def SetWarningAsError(): + global _WarningAsError + _WarningAsError = 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): + os.remove(LogFile) + + _Ch = logging.FileHandler(LogFile) + _Ch.setFormatter(_DebugFormatter) + _DebugLogger.addHandler(_Ch) + + _Ch= logging.FileHandler(LogFile) + _Ch.setFormatter(_InfoFormatter) + _InfoLogger.addHandler(_Ch) + + _Ch = logging.FileHandler(LogFile) + _Ch.setFormatter(_ErrorFormatter) + _ErrorLogger.addHandler(_Ch) + +if __name__ == '__main__': + pass + diff --git a/BaseTools/Source/Python/Common/FdfClassObject.py b/BaseTools/Source/Python/Common/FdfClassObject.py new file mode 100644 index 0000000000..e0df1c20c2 --- /dev/null +++ b/BaseTools/Source/Python/Common/FdfClassObject.py @@ -0,0 +1,116 @@ +## @file +# This file is used to define each component of FDF file +# +# Copyright (c) 2008, 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 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 +# +from FdfParserLite import FdfParser +from Table.TableFdf import TableFdf +from CommonDataClass.DataClass import MODEL_FILE_FDF, MODEL_PCD, MODEL_META_DATA_COMPONENT +from String import NormPath + +## FdfObject +# +# This class defined basic Fdf object which is used by inheriting +# +# @param object: Inherited from object class +# +class FdfObject(object): + def __init__(self): + object.__init__() + +## Fdf +# +# This class defined the structure used in Fdf object +# +# @param FdfObject: Inherited from FdfObject class +# @param Filename: Input value for Ffilename of Fdf file, default is None +# @param WorkspaceDir: Input value for current workspace directory, default is None +# +class Fdf(FdfObject): + def __init__(self, Filename = None, IsToDatabase = False, WorkspaceDir = None, Database = None): + self.WorkspaceDir = WorkspaceDir + self.IsToDatabase = IsToDatabase + + self.Cur = Database.Cur + self.TblFile = Database.TblFile + self.TblFdf = Database.TblFdf + self.FileID = -1 + self.FileList = {} + + # + # Load Fdf file if filename is not None + # + if Filename != None: + self.LoadFdfFile(Filename) + + # + # Insert a FDF file record into database + # + def InsertFile(self, Filename): + FileID = -1 + Filename = NormPath(Filename) + if Filename not in self.FileList: + FileID = self.TblFile.InsertFile(Filename, MODEL_FILE_FDF) + self.FileList[Filename] = FileID + + return self.FileList[Filename] + + + ## Load Fdf file + # + # Load the file if it exists + # + # @param Filename: Input value for filename of Fdf file + # + def LoadFdfFile(self, Filename): + FileList = [] + # + # Parse Fdf file + # + Filename = NormPath(Filename) + Fdf = FdfParser(Filename) + Fdf.ParseFile() + + # + # Insert inf file and pcd information + # + if self.IsToDatabase: + (Model, Value1, Value2, Value3, Arch, BelongsToItem, BelongsToFile, StartLine, StartColumn, EndLine, EndColumn, Enabled) = \ + (0, '', '', '', 'COMMON', -1, -1, -1, -1, -1, -1, 0) + for Index in range(0, len(Fdf.Profile.PcdDict)): + pass + for Key in Fdf.Profile.PcdDict.keys(): + Model = MODEL_PCD + Value1 = '' + Value2 = ".".join((Key[1], Key[0])) + FileName = Fdf.Profile.PcdFileLineDict[Key][0] + StartLine = Fdf.Profile.PcdFileLineDict[Key][1] + BelongsToFile = self.InsertFile(FileName) + self.TblFdf.Insert(Model, Value1, Value2, Value3, Arch, BelongsToItem, BelongsToFile, StartLine, StartColumn, EndLine, EndColumn, Enabled) + for Index in range(0, len(Fdf.Profile.InfList)): + Model = MODEL_META_DATA_COMPONENT + Value1 = Fdf.Profile.InfList[Index] + Value2 = '' + FileName = Fdf.Profile.InfFileLineList[Index][0] + StartLine = Fdf.Profile.InfFileLineList[Index][1] + BelongsToFile = self.InsertFile(FileName) + self.TblFdf.Insert(Model, Value1, Value2, Value3, Arch, BelongsToItem, BelongsToFile, StartLine, StartColumn, EndLine, EndColumn, Enabled) + +## +# +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +# +if __name__ == '__main__': + pass diff --git a/BaseTools/Source/Python/Common/FdfParserLite.py b/BaseTools/Source/Python/Common/FdfParserLite.py new file mode 100644 index 0000000000..59006fa5c5 --- /dev/null +++ b/BaseTools/Source/Python/Common/FdfParserLite.py @@ -0,0 +1,3603 @@ +## @file +# parse FDF file +# +# Copyright (c) 2007, 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 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 re +import os + +import CommonDataClass.FdfClass + +##define T_CHAR_SPACE ' ' +##define T_CHAR_NULL '\0' +##define T_CHAR_CR '\r' +##define T_CHAR_TAB '\t' +##define T_CHAR_LF '\n' +##define T_CHAR_SLASH '/' +##define T_CHAR_BACKSLASH '\\' +##define T_CHAR_DOUBLE_QUOTE '\"' +##define T_CHAR_SINGLE_QUOTE '\'' +##define T_CHAR_STAR '*' +##define T_CHAR_HASH '#' + +(T_CHAR_SPACE, T_CHAR_NULL, T_CHAR_CR, T_CHAR_TAB, T_CHAR_LF, T_CHAR_SLASH, \ +T_CHAR_BACKSLASH, T_CHAR_DOUBLE_QUOTE, T_CHAR_SINGLE_QUOTE, T_CHAR_STAR, T_CHAR_HASH) = \ +(' ', '\0', '\r', '\t', '\n', '/', '\\', '\"', '\'', '*', '#') + +SEPERATOR_TUPLE = ('=', '|', ',', '{', '}') + +IncludeFileList = [] +# Macro passed from command line, which has greatest priority and can NOT be overridden by those in FDF +InputMacroDict = {} +# All Macro values when parsing file, not replace existing Macro +AllMacroList = [] + +def GetRealFileLine (File, Line): + + InsertedLines = 0 + for Profile in IncludeFileList: + if Line >= Profile.InsertStartLineNumber and Line < Profile.InsertStartLineNumber + Profile.InsertAdjust + len(Profile.FileLinesList): + return (Profile.FileName, Line - Profile.InsertStartLineNumber + 1) + if Line >= Profile.InsertStartLineNumber + Profile.InsertAdjust + len(Profile.FileLinesList): + InsertedLines += Profile.InsertAdjust + len(Profile.FileLinesList) + + return (File, Line - InsertedLines) + +## The exception class that used to report error messages when parsing FDF +# +# Currently the "ToolName" is set to be "FDF Parser". +# +class Warning (Exception): + ## The constructor + # + # @param self The object pointer + # @param Str The message to record + # @param File The FDF name + # @param Line The Line number that error occurs + # + def __init__(self, Str, File = None, Line = None): + + FileLineTuple = GetRealFileLine(File, Line) + self.FileName = FileLineTuple[0] + self.LineNumber = FileLineTuple[1] + self.message = Str + str(self.LineNumber) + self.ToolName = 'FDF Parser' + +## The MACRO class that used to record macro value data when parsing include file +# +# +class MacroProfile : + ## The constructor + # + # @param self The object pointer + # @param FileName The file that to be parsed + # + def __init__(self, FileName, Line): + self.FileName = FileName + self.DefinedAtLine = Line + self.MacroName = None + self.MacroValue = None + +## The Include file content class that used to record file data when parsing include file +# +# May raise Exception when opening file. +# +class IncludeFileProfile : + ## The constructor + # + # @param self The object pointer + # @param FileName The file that to be parsed + # + def __init__(self, FileName): + self.FileName = FileName + self.FileLinesList = [] + try: + fsock = open(FileName, "rb", 0) + try: + self.FileLinesList = fsock.readlines() + finally: + fsock.close() + + except IOError: + raise Warning("Error when opening file %s" % FileName) + + self.InsertStartLineNumber = None + self.InsertAdjust = 0 + +## The FDF content class that used to record file data when parsing FDF +# +# May raise Exception when opening file. +# +class FileProfile : + ## The constructor + # + # @param self The object pointer + # @param FileName The file that to be parsed + # + def __init__(self, FileName): + self.FileLinesList = [] + try: + fsock = open(FileName, "rb", 0) + try: + self.FileLinesList = fsock.readlines() + finally: + fsock.close() + + except IOError: + raise Warning("Error when opening file %s" % FileName) + + self.PcdDict = {} + self.InfList = [] + + self.PcdFileLineDict = {} + self.InfFileLineList = [] + + self.FdDict = {} + self.FvDict = {} + self.CapsuleList = [] +# self.VtfList = [] +# self.RuleDict = {} + +## The syntax parser for FDF +# +# PreprocessFile method should be called prior to ParseFile +# CycleReferenceCheck method can detect cycles in FDF contents +# +# GetNext*** procedures mean these procedures will get next token first, then make judgement. +# Get*** procedures mean these procedures will make judgement on current token only. +# +class FdfParser(object): + ## The constructor + # + # @param self The object pointer + # @param FileName The file that to be parsed + # + def __init__(self, FileName): + self.Profile = FileProfile(FileName) + self.FileName = FileName + self.CurrentLineNumber = 1 + self.CurrentOffsetWithinLine = 0 + self.CurrentFdName = None + self.CurrentFvName = None + self.__Token = "" + self.__SkippedChars = "" + + self.__WipeOffArea = [] + + ## __IsWhiteSpace() method + # + # Whether char at current FileBufferPos is whitespace + # + # @param self The object pointer + # @param Char The char to test + # @retval True The char is a kind of white space + # @retval False The char is NOT a kind of white space + # + def __IsWhiteSpace(self, Char): + if Char in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_SPACE, T_CHAR_TAB, T_CHAR_LF): + return True + else: + return False + + ## __SkipWhiteSpace() method + # + # Skip white spaces from current char, return number of chars skipped + # + # @param self The object pointer + # @retval Count The number of chars skipped + # + def __SkipWhiteSpace(self): + Count = 0 + while not self.__EndOfFile(): + Count += 1 + if self.__CurrentChar() in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_LF, T_CHAR_SPACE, T_CHAR_TAB): + self.__SkippedChars += str(self.__CurrentChar()) + self.__GetOneChar() + + else: + Count = Count - 1 + return Count + + ## __EndOfFile() method + # + # Judge current buffer pos is at file end + # + # @param self The object pointer + # @retval True Current File buffer position is at file end + # @retval False Current File buffer position is NOT at file end + # + def __EndOfFile(self): + NumberOfLines = len(self.Profile.FileLinesList) + SizeOfLastLine = len(self.Profile.FileLinesList[-1]) + if self.CurrentLineNumber == NumberOfLines and self.CurrentOffsetWithinLine >= SizeOfLastLine - 1: + return True + elif self.CurrentLineNumber > NumberOfLines: + return True + else: + return False + + ## __EndOfLine() method + # + # Judge current buffer pos is at line end + # + # @param self The object pointer + # @retval True Current File buffer position is at line end + # @retval False Current File buffer position is NOT at line end + # + def __EndOfLine(self): + if self.CurrentLineNumber > len(self.Profile.FileLinesList): + return True + SizeOfCurrentLine = len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) + if self.CurrentOffsetWithinLine >= SizeOfCurrentLine: + return True + else: + return False + + ## Rewind() method + # + # Reset file data buffer to the initial state + # + # @param self The object pointer + # + def Rewind(self): + self.CurrentLineNumber = 1 + self.CurrentOffsetWithinLine = 0 + + ## __UndoOneChar() method + # + # Go back one char in the file buffer + # + # @param self The object pointer + # @retval True Successfully go back one char + # @retval False Not able to go back one char as file beginning reached + # + def __UndoOneChar(self): + + if self.CurrentLineNumber == 1 and self.CurrentOffsetWithinLine == 0: + return False + elif self.CurrentOffsetWithinLine == 0: + self.CurrentLineNumber -= 1 + self.CurrentOffsetWithinLine = len(self.__CurrentLine()) - 1 + else: + self.CurrentOffsetWithinLine -= 1 + return True + + ## __GetOneChar() method + # + # Move forward one char in the file buffer + # + # @param self The object pointer + # + def __GetOneChar(self): + if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1: + self.CurrentLineNumber += 1 + self.CurrentOffsetWithinLine = 0 + else: + self.CurrentOffsetWithinLine += 1 + + ## __CurrentChar() method + # + # Get the char pointed to by the file buffer pointer + # + # @param self The object pointer + # @retval Char Current char + # + def __CurrentChar(self): + return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] + + ## __NextChar() method + # + # Get the one char pass the char pointed to by the file buffer pointer + # + # @param self The object pointer + # @retval Char Next char + # + def __NextChar(self): + if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1: + return self.Profile.FileLinesList[self.CurrentLineNumber][0] + else: + return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine + 1] + + ## __SetCurrentCharValue() method + # + # Modify the value of current char + # + # @param self The object pointer + # @param Value The new value of current char + # + def __SetCurrentCharValue(self, Value): + self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] = Value + + ## __CurrentLine() method + # + # Get the list that contains current line contents + # + # @param self The object pointer + # @retval List current line contents + # + def __CurrentLine(self): + return self.Profile.FileLinesList[self.CurrentLineNumber - 1] + + def __StringToList(self): + self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesList] + self.Profile.FileLinesList[-1].append(' ') + + def __ReplaceMacros(self, Str, File, Line): + MacroEnd = 0 + while Str.find('$(', MacroEnd) >= 0: + MacroStart = Str.find('$(', MacroEnd) + if Str.find(')', MacroStart) > 0: + MacroEnd = Str.find(')', MacroStart) + Name = Str[MacroStart + 2 : MacroEnd] + Value = None + if Name in InputMacroDict: + Value = InputMacroDict[Name] + + else: + for Profile in AllMacroList: + if Profile.FileName == File and Profile.MacroName == Name and Profile.DefinedAtLine <= Line: + Value = Profile.MacroValue + + if Value != None: + Str = Str.replace('$(' + Name + ')', Value) + MacroEnd = MacroStart + len(Value) + + else: + raise Warning("Macro not complete At Line ", self.FileName, self.CurrentLineNumber) + return Str + + def __ReplaceFragment(self, StartPos, EndPos, Value = ' '): + if StartPos[0] == EndPos[0]: + Offset = StartPos[1] + while Offset <= EndPos[1]: + self.Profile.FileLinesList[StartPos[0]][Offset] = Value + Offset += 1 + return + + Offset = StartPos[1] + while self.Profile.FileLinesList[StartPos[0]][Offset] not in ('\r', '\n'): + self.Profile.FileLinesList[StartPos[0]][Offset] = Value + Offset += 1 + + Line = StartPos[0] + while Line < EndPos[0]: + Offset = 0 + while self.Profile.FileLinesList[Line][Offset] not in ('\r', '\n'): + self.Profile.FileLinesList[Line][Offset] = Value + Offset += 1 + Line += 1 + + Offset = 0 + while Offset <= EndPos[1]: + self.Profile.FileLinesList[EndPos[0]][Offset] = Value + Offset += 1 + + + ## PreprocessFile() method + # + # Preprocess file contents, replace comments with spaces. + # In the end, rewind the file buffer pointer to the beginning + # BUGBUG: No !include statement processing contained in this procedure + # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1] + # + # @param self The object pointer + # + def PreprocessFile(self): + + self.Rewind() + InComment = False + DoubleSlashComment = False + HashComment = False + # HashComment in quoted string " " is ignored. + InString = False + + while not self.__EndOfFile(): + + if self.__CurrentChar() == T_CHAR_DOUBLE_QUOTE and not InComment: + InString = not InString + # meet new line, then no longer in a comment for // and '#' + if self.__CurrentChar() == T_CHAR_LF: + self.CurrentLineNumber += 1 + self.CurrentOffsetWithinLine = 0 + if InComment and DoubleSlashComment: + InComment = False + DoubleSlashComment = False + if InComment and HashComment: + InComment = False + HashComment = False + # check for */ comment end + elif InComment and not DoubleSlashComment and not HashComment and self.__CurrentChar() == T_CHAR_STAR and self.__NextChar() == T_CHAR_SLASH: + self.__SetCurrentCharValue(T_CHAR_SPACE) + self.__GetOneChar() + self.__SetCurrentCharValue(T_CHAR_SPACE) + self.__GetOneChar() + InComment = False + # set comments to spaces + elif InComment: + self.__SetCurrentCharValue(T_CHAR_SPACE) + self.__GetOneChar() + # check for // comment + elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_SLASH and not self.__EndOfLine(): + InComment = True + DoubleSlashComment = True + # check for '#' comment + elif self.__CurrentChar() == T_CHAR_HASH and not self.__EndOfLine() and not InString: + InComment = True + HashComment = True + # check for /* comment start + elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_STAR: + self.__SetCurrentCharValue( T_CHAR_SPACE) + self.__GetOneChar() + self.__SetCurrentCharValue( T_CHAR_SPACE) + self.__GetOneChar() + InComment = True + else: + self.__GetOneChar() + + # restore from ListOfList to ListOfString + self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList] + self.Rewind() + + ## PreprocessIncludeFile() method + # + # Preprocess file contents, replace !include statements with file contents. + # In the end, rewind the file buffer pointer to the beginning + # + # @param self The object pointer + # + def PreprocessIncludeFile(self): + + while self.__GetNextToken(): + + if self.__Token == '!include': + IncludeLine = self.CurrentLineNumber + IncludeOffset = self.CurrentOffsetWithinLine - len('!include') + if not self.__GetNextToken(): + raise Warning("expected include file name At Line ", self.FileName, self.CurrentLineNumber) + IncFileName = self.__Token + if not os.path.isabs(IncFileName): + if IncFileName.startswith('$(WORKSPACE)'): + Str = IncFileName.replace('$(WORKSPACE)', os.environ.get('WORKSPACE')) + if os.path.exists(Str): + if not os.path.isabs(Str): + Str = os.path.abspath(Str) + IncFileName = Str + else: + # file is in the same dir with FDF file + FullFdf = self.FileName + if not os.path.isabs(self.FileName): + FullFdf = os.path.join(os.environ.get('WORKSPACE'), self.FileName) + + IncFileName = os.path.join(os.path.dirname(FullFdf), IncFileName) + + if not os.path.exists(os.path.normpath(IncFileName)): + raise Warning("Include file not exists At Line ", self.FileName, self.CurrentLineNumber) + + IncFileProfile = IncludeFileProfile(os.path.normpath(IncFileName)) + + CurrentLine = self.CurrentLineNumber + CurrentOffset = self.CurrentOffsetWithinLine + # list index of the insertion, note that line number is 'CurrentLine + 1' + InsertAtLine = CurrentLine + IncFileProfile.InsertStartLineNumber = InsertAtLine + 1 + # deal with remaining portions after "!include filename", if exists. + if self.__GetNextToken(): + if self.CurrentLineNumber == CurrentLine: + RemainingLine = self.__CurrentLine()[CurrentOffset:] + self.Profile.FileLinesList.insert(self.CurrentLineNumber, RemainingLine) + IncFileProfile.InsertAdjust += 1 + self.CurrentLineNumber += 1 + self.CurrentOffsetWithinLine = 0 + + for Line in IncFileProfile.FileLinesList: + self.Profile.FileLinesList.insert(InsertAtLine, Line) + self.CurrentLineNumber += 1 + InsertAtLine += 1 + + IncludeFileList.append(IncFileProfile) + + # comment out the processed include file statement + TempList = list(self.Profile.FileLinesList[IncludeLine - 1]) + TempList.insert(IncludeOffset, '#') + self.Profile.FileLinesList[IncludeLine - 1] = ''.join(TempList) + + self.Rewind() + + ## PreprocessIncludeFile() method + # + # Preprocess file contents, replace !include statements with file contents. + # In the end, rewind the file buffer pointer to the beginning + # + # @param self The object pointer + # + def PreprocessConditionalStatement(self): + # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined] + IfList = [] + while self.__GetNextToken(): + if self.__Token == 'DEFINE': + DefineLine = self.CurrentLineNumber - 1 + DefineOffset = self.CurrentOffsetWithinLine - len('DEFINE') + if not self.__GetNextToken(): + raise Warning("expected Macro name At Line ", self.FileName, self.CurrentLineNumber) + Macro = self.__Token + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected value At Line ", self.FileName, self.CurrentLineNumber) + + if self.__GetStringData(): + pass + Value = self.__Token + if not Macro in InputMacroDict: + FileLineTuple = GetRealFileLine(self.FileName, DefineLine + 1) + MacProfile = MacroProfile(FileLineTuple[0], FileLineTuple[1]) + MacProfile.MacroName = Macro + MacProfile.MacroValue = Value + AllMacroList.append(MacProfile) + self.__WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + + elif self.__Token in ('!ifdef', '!ifndef', '!if'): + IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token)) + IfList.append([IfStartPos, None, None]) + CondLabel = self.__Token + + if not self.__GetNextToken(): + raise Warning("expected Macro name At Line ", self.FileName, self.CurrentLineNumber) + MacroName = self.__Token + NotFlag = False + if MacroName.startswith('!'): + NotFlag = True + MacroName = MacroName[1:] + + NotDefineFlag = False + if CondLabel == '!ifndef': + NotDefineFlag = True + if CondLabel == '!ifdef' or CondLabel == '!ifndef': + if NotFlag: + raise Warning("'NOT' operation not allowed for Macro name At Line ", self.FileName, self.CurrentLineNumber) + + if CondLabel == '!if': + + if not self.__GetNextOp(): + raise Warning("expected !endif At Line ", self.FileName, self.CurrentLineNumber) + + if self.__Token in ('!=', '==', '>', '<', '>=', '<='): + Op = self.__Token + if not self.__GetNextToken(): + raise Warning("expected value At Line ", self.FileName, self.CurrentLineNumber) + if self.__GetStringData(): + pass + MacroValue = self.__Token + ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, Op, MacroValue) + if NotFlag: + ConditionSatisfied = not ConditionSatisfied + BranchDetermined = ConditionSatisfied + else: + self.CurrentOffsetWithinLine -= len(self.__Token) + ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, None, 'Bool') + if NotFlag: + ConditionSatisfied = not ConditionSatisfied + BranchDetermined = ConditionSatisfied + IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined] + if ConditionSatisfied: + self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + + else: + ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1) + if NotDefineFlag: + ConditionSatisfied = not ConditionSatisfied + BranchDetermined = ConditionSatisfied + IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined] + if ConditionSatisfied: + self.__WipeOffArea.append((IfStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + + elif self.__Token in ('!elseif', '!else'): + ElseStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token)) + if len(IfList) <= 0: + raise Warning("Missing !if statement At Line ", self.FileName, self.CurrentLineNumber) + if IfList[-1][1]: + IfList[-1] = [ElseStartPos, False, True] + self.__WipeOffArea.append((ElseStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + else: + self.__WipeOffArea.append((IfList[-1][0], ElseStartPos)) + IfList[-1] = [ElseStartPos, True, IfList[-1][2]] + if self.__Token == '!elseif': + if not self.__GetNextToken(): + raise Warning("expected Macro name At Line ", self.FileName, self.CurrentLineNumber) + MacroName = self.__Token + NotFlag = False + if MacroName.startswith('!'): + NotFlag = True + MacroName = MacroName[1:] + + if not self.__GetNextOp(): + raise Warning("expected !endif At Line ", self.FileName, self.CurrentLineNumber) + + if self.__Token in ('!=', '==', '>', '<', '>=', '<='): + Op = self.__Token + if not self.__GetNextToken(): + raise Warning("expected value At Line ", self.FileName, self.CurrentLineNumber) + if self.__GetStringData(): + pass + MacroValue = self.__Token + ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, Op, MacroValue) + if NotFlag: + ConditionSatisfied = not ConditionSatisfied + + else: + self.CurrentOffsetWithinLine -= len(self.__Token) + ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, None, 'Bool') + if NotFlag: + ConditionSatisfied = not ConditionSatisfied + + IfList[-1] = [IfList[-1][0], ConditionSatisfied, IfList[-1][2]] + + if IfList[-1][1]: + if IfList[-1][2]: + IfList[-1][1] = False + else: + IfList[-1][2] = True + self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + + + elif self.__Token == '!endif': + if IfList[-1][1]: + self.__WipeOffArea.append(((self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len('!endif')), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + else: + self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + + IfList.pop() + + + if len(IfList) > 0: + raise Warning("Missing !endif At Line ", self.FileName, self.CurrentLineNumber) + self.Rewind() + + def __EvaluateConditional(self, Name, Line, Op = None, Value = None): + + FileLineTuple = GetRealFileLine(self.FileName, Line) + if Name in InputMacroDict: + MacroValue = InputMacroDict[Name] + if Op == None: + if Value == 'Bool' and MacroValue == None or MacroValue.upper() == 'FALSE': + return False + return True + elif Op == '!=': + if Value != MacroValue: + return True + else: + return False + elif Op == '==': + if Value == MacroValue: + return True + else: + return False + else: + if (self.__IsHex(Value) or Value.isdigit()) and (self.__IsHex(MacroValue) or (MacroValue != None and MacroValue.isdigit())): + InputVal = long(Value, 0) + MacroVal = long(MacroValue, 0) + if Op == '>': + if MacroVal > InputVal: + return True + else: + return False + elif Op == '>=': + if MacroVal >= InputVal: + return True + else: + return False + elif Op == '<': + if MacroVal < InputVal: + return True + else: + return False + elif Op == '<=': + if MacroVal <= InputVal: + return True + else: + return False + else: + return False + else: + raise Warning("Value %s is not a number At Line ", self.FileName, Line) + + for Profile in AllMacroList: + if Profile.FileName == FileLineTuple[0] and Profile.MacroName == Name and Profile.DefinedAtLine <= FileLineTuple[1]: + if Op == None: + if Value == 'Bool' and Profile.MacroValue == None or Profile.MacroValue.upper() == 'FALSE': + return False + return True + elif Op == '!=': + if Value != Profile.MacroValue: + return True + else: + return False + elif Op == '==': + if Value == Profile.MacroValue: + return True + else: + return False + else: + if (self.__IsHex(Value) or Value.isdigit()) and (self.__IsHex(Profile.MacroValue) or (Profile.MacroValue != None and Profile.MacroValue.isdigit())): + InputVal = long(Value, 0) + MacroVal = long(Profile.MacroValue, 0) + if Op == '>': + if MacroVal > InputVal: + return True + else: + return False + elif Op == '>=': + if MacroVal >= InputVal: + return True + else: + return False + elif Op == '<': + if MacroVal < InputVal: + return True + else: + return False + elif Op == '<=': + if MacroVal <= InputVal: + return True + else: + return False + else: + return False + else: + raise Warning("Value %s is not a number At Line ", self.FileName, Line) + + return False + + ## __IsToken() method + # + # Check whether input string is found from current char position along + # If found, the string value is put into self.__Token + # + # @param self The object pointer + # @param String The string to search + # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive + # @retval True Successfully find string, file buffer pointer moved forward + # @retval False Not able to find string, file buffer pointer not changed + # + def __IsToken(self, String, IgnoreCase = False): + self.__SkipWhiteSpace() + + # Only consider the same line, no multi-line token allowed + StartPos = self.CurrentOffsetWithinLine + index = -1 + if IgnoreCase: + index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper()) + else: + index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String) + if index == 0: + self.CurrentOffsetWithinLine += len(String) + self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine] + return True + return False + + ## __IsKeyword() method + # + # Check whether input keyword is found from current char position along, whole word only! + # If found, the string value is put into self.__Token + # + # @param self The object pointer + # @param Keyword The string to search + # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive + # @retval True Successfully find string, file buffer pointer moved forward + # @retval False Not able to find string, file buffer pointer not changed + # + def __IsKeyword(self, KeyWord, IgnoreCase = False): + self.__SkipWhiteSpace() + + # Only consider the same line, no multi-line token allowed + StartPos = self.CurrentOffsetWithinLine + index = -1 + if IgnoreCase: + index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(KeyWord.upper()) + else: + index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(KeyWord) + if index == 0: + followingChar = self.__CurrentLine()[self.CurrentOffsetWithinLine + len(KeyWord)] + if not str(followingChar).isspace() and followingChar not in SEPERATOR_TUPLE: + return False + self.CurrentOffsetWithinLine += len(KeyWord) + self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine] + return True + return False + + ## __GetNextWord() method + # + # Get next C name from file lines + # If found, the string value is put into self.__Token + # + # @param self The object pointer + # @retval True Successfully find a C name string, file buffer pointer moved forward + # @retval False Not able to find a C name string, file buffer pointer not changed + # + def __GetNextWord(self): + self.__SkipWhiteSpace() + if self.__EndOfFile(): + return False + + TempChar = self.__CurrentChar() + StartPos = self.CurrentOffsetWithinLine + if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_': + self.__GetOneChar() + while not self.__EndOfLine(): + TempChar = self.__CurrentChar() + if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \ + or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-': + self.__GetOneChar() + + else: + break + + self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine] + return True + + return False + + ## __GetNextToken() method + # + # Get next token unit before a seperator + # If found, the string value is put into self.__Token + # + # @param self The object pointer + # @retval True Successfully find a token unit, file buffer pointer moved forward + # @retval False Not able to find a token unit, file buffer pointer not changed + # + def __GetNextToken(self): + # Skip leading spaces, if exist. + self.__SkipWhiteSpace() + if self.__EndOfFile(): + return False + # Record the token start position, the position of the first non-space char. + StartPos = self.CurrentOffsetWithinLine + StartLine = self.CurrentLineNumber + while not self.__EndOfLine(): + TempChar = self.__CurrentChar() + # Try to find the end char that is not a space and not in seperator tuple. + # That is, when we got a space or any char in the tuple, we got the end of token. + if not str(TempChar).isspace() and TempChar not in SEPERATOR_TUPLE: + self.__GetOneChar() + # if we happen to meet a seperator as the first char, we must proceed to get it. + # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens. + elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE: + self.__GetOneChar() + break + else: + break +# else: +# return False + + EndPos = self.CurrentOffsetWithinLine + if self.CurrentLineNumber != StartLine: + EndPos = len(self.Profile.FileLinesList[StartLine-1]) + self.__Token = self.Profile.FileLinesList[StartLine-1][StartPos : EndPos] + if StartPos != self.CurrentOffsetWithinLine: + return True + else: + return False + + def __GetNextOp(self): + # Skip leading spaces, if exist. + self.__SkipWhiteSpace() + if self.__EndOfFile(): + return False + # Record the token start position, the position of the first non-space char. + StartPos = self.CurrentOffsetWithinLine + while not self.__EndOfLine(): + TempChar = self.__CurrentChar() + # Try to find the end char that is not a space + if not str(TempChar).isspace(): + self.__GetOneChar() + else: + break + else: + return False + + if StartPos != self.CurrentOffsetWithinLine: + self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine] + return True + else: + return False + ## __GetNextGuid() method + # + # Get next token unit before a seperator + # If found, the GUID string is put into self.__Token + # + # @param self The object pointer + # @retval True Successfully find a registry format GUID, file buffer pointer moved forward + # @retval False Not able to find a registry format GUID, file buffer pointer not changed + # + def __GetNextGuid(self): + + if not self.__GetNextToken(): + return False + p = re.compile('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}') + if p.match(self.__Token) != None: + return True + else: + self.__UndoToken() + return False + + ## __UndoToken() method + # + # Go back one token unit in file buffer + # + # @param self The object pointer + # + def __UndoToken(self): + self.__UndoOneChar() + while self.__CurrentChar().isspace(): + if not self.__UndoOneChar(): + self.__GetOneChar() + return + + + StartPos = self.CurrentOffsetWithinLine + CurrentLine = self.CurrentLineNumber + while CurrentLine == self.CurrentLineNumber: + + TempChar = self.__CurrentChar() + # Try to find the end char that is not a space and not in seperator tuple. + # That is, when we got a space or any char in the tuple, we got the end of token. + if not str(TempChar).isspace() and not TempChar in SEPERATOR_TUPLE: + if not self.__UndoOneChar(): + break + # if we happen to meet a seperator as the first char, we must proceed to get it. + # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens. + elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE: + return + else: + break + + self.__GetOneChar() + + ## __HexDigit() method + # + # Whether char input is a Hex data bit + # + # @param self The object pointer + # @param TempChar The char to test + # @retval True The char is a Hex data bit + # @retval False The char is NOT a Hex data bit + # + def __HexDigit(self, TempChar): + if (TempChar >= 'a' and TempChar <= 'f') or (TempChar >= 'A' and TempChar <= 'F') \ + or (TempChar >= '0' and TempChar <= '9'): + return True + else: + return False + + def __IsHex(self, HexStr): + if not HexStr.upper().startswith("0X"): + return False + if len(self.__Token) <= 2: + return False + charList = [c for c in HexStr[2 : ] if not self.__HexDigit( c)] + if len(charList) == 0: + return True + else: + return False + ## __GetNextHexNumber() method + # + # Get next HEX data before a seperator + # If found, the HEX data is put into self.__Token + # + # @param self The object pointer + # @retval True Successfully find a HEX data, file buffer pointer moved forward + # @retval False Not able to find a HEX data, file buffer pointer not changed + # + def __GetNextHexNumber(self): + if not self.__GetNextToken(): + return False + if self.__IsHex(self.__Token): + return True + else: + self.__UndoToken() + return False + + ## __GetNextDecimalNumber() method + # + # Get next decimal data before a seperator + # If found, the decimal data is put into self.__Token + # + # @param self The object pointer + # @retval True Successfully find a decimal data, file buffer pointer moved forward + # @retval False Not able to find a decimal data, file buffer pointer not changed + # + def __GetNextDecimalNumber(self): + if not self.__GetNextToken(): + return False + if self.__Token.isdigit(): + return True + else: + self.__UndoToken() + return False + + ## __GetNextPcdName() method + # + # Get next PCD token space C name and PCD C name pair before a seperator + # If found, the decimal data is put into self.__Token + # + # @param self The object pointer + # @retval Tuple PCD C name and PCD token space C name pair + # + def __GetNextPcdName(self): + if not self.__GetNextWord(): + raise Warning("expected PcdTokenSpaceCName.PcdCName At Line ", self.FileName, self.CurrentLineNumber) + pcdTokenSpaceCName = self.__Token + + if not self.__IsToken( "."): + raise Warning("expected PcdTokenSpaceCName.PcdCName At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextWord(): + raise Warning("expected PcdTokenSpaceCName.PcdCName At Line ", self.FileName, self.CurrentLineNumber) + pcdCName = self.__Token + + return (pcdCName, pcdTokenSpaceCName) + + ## __GetStringData() method + # + # Get string contents quoted in "" + # If found, the decimal data is put into self.__Token + # + # @param self The object pointer + # @retval True Successfully find a string data, file buffer pointer moved forward + # @retval False Not able to find a string data, file buffer pointer not changed + # + def __GetStringData(self): + if self.__Token.startswith("\"") or self.__Token.startswith("L\""): + self.__UndoToken() + self.__SkipToToken("\"") + currentLineNumber = self.CurrentLineNumber + + if not self.__SkipToToken("\""): + raise Warning("Missing Quote \" for String At Line ", self.FileName, self.CurrentLineNumber) + if currentLineNumber != self.CurrentLineNumber: + raise Warning("Missing Quote \" for String At Line ", self.FileName, self.CurrentLineNumber) + self.__Token = self.__SkippedChars.rstrip('\"') + return True + + elif self.__Token.startswith("\'") or self.__Token.startswith("L\'"): + self.__UndoToken() + self.__SkipToToken("\'") + currentLineNumber = self.CurrentLineNumber + + if not self.__SkipToToken("\'"): + raise Warning("Missing Quote \' for String At Line ", self.FileName, self.CurrentLineNumber) + if currentLineNumber != self.CurrentLineNumber: + raise Warning("Missing Quote \' for String At Line ", self.FileName, self.CurrentLineNumber) + self.__Token = self.__SkippedChars.rstrip('\'') + return True + + else: + return False + + ## __SkipToToken() method + # + # Search forward in file buffer for the string + # The skipped chars are put into self.__SkippedChars + # + # @param self The object pointer + # @param String The string to search + # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive + # @retval True Successfully find the string, file buffer pointer moved forward + # @retval False Not able to find the string, file buffer pointer not changed + # + def __SkipToToken(self, String, IgnoreCase = False): + StartPos = self.GetFileBufferPos() + + self.__SkippedChars = "" + while not self.__EndOfFile(): + index = -1 + if IgnoreCase: + index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper()) + else: + index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String) + if index == 0: + self.CurrentOffsetWithinLine += len(String) + self.__SkippedChars += String + return True + self.__SkippedChars += str(self.__CurrentChar()) + self.__GetOneChar() + + self.SetFileBufferPos( StartPos) + self.__SkippedChars = "" + return False + + ## GetFileBufferPos() method + # + # Return the tuple of current line and offset within the line + # + # @param self The object pointer + # @retval Tuple Line number and offset pair + # + def GetFileBufferPos(self): + return (self.CurrentLineNumber, self.CurrentOffsetWithinLine) + + ## SetFileBufferPos() method + # + # Restore the file buffer position + # + # @param self The object pointer + # @param Pos The new file buffer position + # + def SetFileBufferPos(self, Pos): + (self.CurrentLineNumber, self.CurrentOffsetWithinLine) = Pos + + ## ParseFile() method + # + # Parse the file profile buffer to extract fd, fv ... information + # Exception will be raised if syntax error found + # + # @param self The object pointer + # + def ParseFile(self): + + try: + self.__StringToList() + self.PreprocessFile() + self.PreprocessIncludeFile() + self.__StringToList() + self.PreprocessFile() + self.PreprocessConditionalStatement() + self.__StringToList() + for Pos in self.__WipeOffArea: + self.__ReplaceFragment(Pos[0], Pos[1]) + self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList] + + while self.__GetDefines(): + pass + + Index = 0 + while Index < len(self.Profile.FileLinesList): + FileLineTuple = GetRealFileLine(self.FileName, Index + 1) + self.Profile.FileLinesList[Index] = self.__ReplaceMacros(self.Profile.FileLinesList[Index], FileLineTuple[0], FileLineTuple[1]) + Index += 1 + + while self.__GetFd(): + pass + + while self.__GetFv(): + pass + + while self.__GetCapsule(): + pass + +# while self.__GetVtf(): +# pass +# +# while self.__GetRule(): +# pass + + + except Warning, X: + self.__UndoToken() + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + X.message += '\nGot Token: \"%s\" from File %s\n' % (self.__Token, FileLineTuple[0]) + \ + 'Previous Token: \"%s\" At line: %d, Offset Within Line: %d\n' \ + % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :].rstrip('\n').rstrip('\r'), FileLineTuple[1], self.CurrentOffsetWithinLine) + raise + + ## __GetDefines() method + # + # Get Defines section contents and store its data into AllMacrosList + # + # @param self The object pointer + # @retval True Successfully find a Defines + # @retval False Not able to find a Defines + # + def __GetDefines(self): + + if not self.__GetNextToken(): + return False + + S = self.__Token.upper() + if S.startswith("[") and not S.startswith("[DEFINES"): + if not S.startswith("[FD.") and not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \ + and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."): + raise Warning("Unknown section or section appear sequence error (The correct sequence should be [DEFINES], [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber) + self.__UndoToken() + return False + + self.__UndoToken() + if not self.__IsToken("[DEFINES", True): + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ + # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) + raise Warning("expected [DEFINES", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "]"): + raise Warning("expected ']'", self.FileName, self.CurrentLineNumber) + + while self.__GetNextWord(): + Macro = self.__Token + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken() or self.__Token.startswith('['): + raise Warning("expected MACRO value", self.FileName, self.CurrentLineNumber) + Value = self.__Token + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + MacProfile = MacroProfile(FileLineTuple[0], FileLineTuple[1]) + MacProfile.MacroName = Macro + MacProfile.MacroValue = Value + AllMacroList.append(MacProfile) + + return False + + ## __GetFd() method + # + # Get FD section contents and store its data into FD dictionary of self.Profile + # + # @param self The object pointer + # @retval True Successfully find a FD + # @retval False Not able to find a FD + # + def __GetFd(self): + + if not self.__GetNextToken(): + return False + + S = self.__Token.upper() + if S.startswith("[") and not S.startswith("[FD."): + if not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \ + and not S.startswith("[VTF.") and not S.startswith("[RULE."): + raise Warning("Unknown section At Line ", self.FileName, self.CurrentLineNumber) + self.__UndoToken() + return False + + self.__UndoToken() + if not self.__IsToken("[FD.", True): + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ + % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) + raise Warning("expected [FD.] At Line ", self.FileName, self.CurrentLineNumber) + + FdName = self.__GetUiName() + self.CurrentFdName = FdName.upper() + + if not self.__IsToken( "]"): + raise Warning("expected ']' At Line ", self.FileName, self.CurrentLineNumber) + + FdObj = CommonDataClass.FdfClass.FDClassObject() + FdObj.FdUiName = self.CurrentFdName + self.Profile.FdDict[self.CurrentFdName] = FdObj + Status = self.__GetCreateFile(FdObj) + if not Status: + raise Warning("FD name error At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetTokenStatements(FdObj): + return False + + self.__GetDefineStatements(FdObj) + + self.__GetSetStatements(FdObj) + + if not self.__GetRegionLayout(FdObj): + raise Warning("expected region layout At Line ", self.FileName, self.CurrentLineNumber) + + while self.__GetRegionLayout(FdObj): + pass + return True + + ## __GetUiName() method + # + # Return the UI name of a section + # + # @param self The object pointer + # @retval FdName UI name + # + def __GetUiName(self): + FdName = "" + if self.__GetNextWord(): + FdName = self.__Token + + return FdName + + ## __GetCreateFile() method + # + # Return the output file name of object + # + # @param self The object pointer + # @param Obj object whose data will be stored in file + # @retval FdName UI name + # + def __GetCreateFile(self, Obj): + + if self.__IsKeyword( "CREATE_FILE"): + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected file name At Line ", self.FileName, self.CurrentLineNumber) + + FileName = self.__Token + Obj.CreateFileName = FileName + + return True + + ## __GetTokenStatements() method + # + # Get token statements + # + # @param self The object pointer + # @param Obj for whom token statement is got + # @retval True Successfully find a token statement + # @retval False Not able to find a token statement + # + def __GetTokenStatements(self, Obj): + if not self.__IsKeyword( "BaseAddress"): + raise Warning("BaseAddress missing At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextHexNumber(): + raise Warning("expected Hex base address At Line ", self.FileName, self.CurrentLineNumber) + + Obj.BaseAddress = self.__Token + + if self.__IsToken( "|"): + pcdPair = self.__GetNextPcdName() + Obj.BaseAddressPcd = pcdPair + self.Profile.PcdDict[pcdPair] = long(Obj.BaseAddress, 0) + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple + + if not self.__IsKeyword( "Size"): + raise Warning("Size missing At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextHexNumber(): + raise Warning("expected Hex size At Line ", self.FileName, self.CurrentLineNumber) + + + Obj.Size = long(self.__Token, 0) + + if self.__IsToken( "|"): + pcdPair = self.__GetNextPcdName() + Obj.SizePcd = pcdPair + self.Profile.PcdDict[pcdPair] = Obj.Size + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple + + if not self.__IsKeyword( "ErasePolarity"): + raise Warning("ErasePolarity missing At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Erase Polarity At Line ", self.FileName, self.CurrentLineNumber) + + if self.__Token != "1" and self.__Token != "0": + raise Warning("expected 1 or 0 Erase Polarity At Line ", self.FileName, self.CurrentLineNumber) + + Obj.ErasePolarity = self.__Token + + Status = self.__GetBlockStatements(Obj) + return Status + + ## __GetAddressStatements() method + # + # Get address statements + # + # @param self The object pointer + # @param Obj for whom address statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetAddressStatements(self, Obj): + + if self.__IsKeyword("BsBaseAddress"): + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber(): + raise Warning("expected address At Line ", self.FileName, self.CurrentLineNumber) + + BsAddress = long(self.__Token, 0) + Obj.BsBaseAddress = BsAddress + + if self.__IsKeyword("RtBaseAddress"): + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber(): + raise Warning("expected address At Line ", self.FileName, self.CurrentLineNumber) + + RtAddress = long(self.__Token, 0) + Obj.RtBaseAddress = RtAddress + + ## __GetBlockStatements() method + # + # Get block statements + # + # @param self The object pointer + # @param Obj for whom block statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetBlockStatements(self, Obj): + + if not self.__GetBlockStatement(Obj): + raise Warning("expected block statement At Line ", self.FileName, self.CurrentLineNumber) + + while self.__GetBlockStatement(Obj): + pass + return True + + ## __GetBlockStatement() method + # + # Get block statement + # + # @param self The object pointer + # @param Obj for whom block statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetBlockStatement(self, Obj): + if not self.__IsKeyword( "BlockSize"): + return False + + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber(): + raise Warning("expected Hex block size At Line ", self.FileName, self.CurrentLineNumber) + + BlockSize = long(self.__Token, 0) + BlockSizePcd = None + if self.__IsToken( "|"): + PcdPair = self.__GetNextPcdName() + BlockSizePcd = PcdPair + self.Profile.PcdDict[PcdPair] = BlockSize + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple + + BlockNumber = None + if self.__IsKeyword( "NumBlocks"): + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber(): + raise Warning("expected block numbers At Line ", self.FileName, self.CurrentLineNumber) + + BlockNumber = long(self.__Token, 0) + + Obj.BlockSizeList.append((BlockSize, BlockNumber, BlockSizePcd)) + return True + + ## __GetDefineStatements() method + # + # Get define statements + # + # @param self The object pointer + # @param Obj for whom define statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetDefineStatements(self, Obj): + while self.__GetDefineStatement( Obj): + pass + + ## __GetDefineStatement() method + # + # Get define statement + # + # @param self The object pointer + # @param Obj for whom define statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetDefineStatement(self, Obj): + if self.__IsKeyword("DEFINE"): + self.__GetNextToken() + Macro = self.__Token + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected value At Line ", self.FileName, self.CurrentLineNumber) + + Value = self.__Token + Macro = '$(' + Macro + ')' + Obj.DefineVarDict[Macro] = Value + return True + + return False + + ## __GetSetStatements() method + # + # Get set statements + # + # @param self The object pointer + # @param Obj for whom set statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetSetStatements(self, Obj): + while self.__GetSetStatement(Obj): + pass + + ## __GetSetStatement() method + # + # Get set statement + # + # @param self The object pointer + # @param Obj for whom set statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetSetStatement(self, Obj): + if self.__IsKeyword("SET"): + PcdPair = self.__GetNextPcdName() + + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected value At Line ", self.FileName, self.CurrentLineNumber) + + Value = self.__Token + if Value.startswith("{"): + # deal with value with {} + if not self.__SkipToToken( "}"): + raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber) + Value += self.__SkippedChars + + Obj.SetVarDict[PcdPair] = Value + self.Profile.PcdDict[PcdPair] = Value + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple + return True + + return False + + ## __GetRegionLayout() method + # + # Get region layout for FD + # + # @param self The object pointer + # @param Fd for whom region is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetRegionLayout(self, Fd): + if not self.__GetNextHexNumber(): + return False + + RegionObj = CommonDataClass.FdfClass.RegionClassObject() + RegionObj.Offset = long(self.__Token, 0) + Fd.RegionList.append(RegionObj) + + if not self.__IsToken( "|"): + raise Warning("expected '|' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextHexNumber(): + raise Warning("expected Region Size At Line ", self.FileName, self.CurrentLineNumber) + RegionObj.Size = long(self.__Token, 0) + + if not self.__GetNextWord(): + return True + + if not self.__Token in ("SET", "FV", "FILE", "DATA"): + self.__UndoToken() + RegionObj.PcdOffset = self.__GetNextPcdName() + self.Profile.PcdDict[RegionObj.PcdOffset] = RegionObj.Offset + long(Fd.BaseAddress, 0) + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + self.Profile.PcdFileLineDict[RegionObj.PcdOffset] = FileLineTuple + if self.__IsToken( "|"): + RegionObj.PcdSize = self.__GetNextPcdName() + self.Profile.PcdDict[RegionObj.PcdSize] = RegionObj.Size + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + self.Profile.PcdFileLineDict[RegionObj.PcdSize] = FileLineTuple + + if not self.__GetNextWord(): + return True + + if self.__Token == "SET": + self.__UndoToken() + self.__GetSetStatements( RegionObj) + if not self.__GetNextWord(): + return True + + if self.__Token == "FV": + self.__UndoToken() + self.__GetRegionFvType( RegionObj) + + elif self.__Token == "FILE": + self.__UndoToken() + self.__GetRegionFileType( RegionObj) + + else: + self.__UndoToken() + self.__GetRegionDataType( RegionObj) + + return True + + ## __GetRegionFvType() method + # + # Get region fv data for region + # + # @param self The object pointer + # @param RegionObj for whom region data is got + # + def __GetRegionFvType(self, RegionObj): + + if not self.__IsKeyword( "FV"): + raise Warning("expected Keyword 'FV' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected FV name At Line ", self.FileName, self.CurrentLineNumber) + + RegionObj.RegionType = "FV" + RegionObj.RegionDataList.append(self.__Token) + + while self.__IsKeyword( "FV"): + + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected FV name At Line ", self.FileName, self.CurrentLineNumber) + + RegionObj.RegionDataList.append(self.__Token) + + ## __GetRegionFileType() method + # + # Get region file data for region + # + # @param self The object pointer + # @param RegionObj for whom region data is got + # + def __GetRegionFileType(self, RegionObj): + + if not self.__IsKeyword( "FILE"): + raise Warning("expected Keyword 'FILE' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected File name At Line ", self.FileName, self.CurrentLineNumber) + + RegionObj.RegionType = "FILE" + RegionObj.RegionDataList.append( self.__Token) + + while self.__IsKeyword( "FILE"): + + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected FILE name At Line ", self.FileName, self.CurrentLineNumber) + + RegionObj.RegionDataList.append(self.__Token) + + ## __GetRegionDataType() method + # + # Get region array data for region + # + # @param self The object pointer + # @param RegionObj for whom region data is got + # + def __GetRegionDataType(self, RegionObj): + + if not self.__IsKeyword( "DATA"): + raise Warning("expected Region Data type At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "{"): + raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextHexNumber(): + raise Warning("expected Hex byte At Line ", self.FileName, self.CurrentLineNumber) + + if len(self.__Token) > 4: + raise Warning("Hex byte(must be 2 digits) too long At Line ", self.FileName, self.CurrentLineNumber) + + DataString = self.__Token + DataString += "," + + while self.__IsToken(","): + if not self.__GetNextHexNumber(): + raise Warning("Invalid Hex number At Line ", self.FileName, self.CurrentLineNumber) + if len(self.__Token) > 4: + raise Warning("Hex byte(must be 2 digits) too long At Line ", self.FileName, self.CurrentLineNumber) + DataString += self.__Token + DataString += "," + + if not self.__IsToken( "}"): + raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber) + + DataString = DataString.rstrip(",") + RegionObj.RegionType = "DATA" + RegionObj.RegionDataList.append( DataString) + + while self.__IsKeyword( "DATA"): + + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "{"): + raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextHexNumber(): + raise Warning("expected Hex byte At Line ", self.FileName, self.CurrentLineNumber) + + if len(self.__Token) > 4: + raise Warning("Hex byte(must be 2 digits) too long At Line ", self.FileName, self.CurrentLineNumber) + + DataString = self.__Token + DataString += "," + + while self.__IsToken(","): + self.__GetNextHexNumber() + if len(self.__Token) > 4: + raise Warning("Hex byte(must be 2 digits) too long At Line ", self.FileName, self.CurrentLineNumber) + DataString += self.__Token + DataString += "," + + if not self.__IsToken( "}"): + raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber) + + DataString = DataString.rstrip(",") + RegionObj.RegionDataList.append( DataString) + + ## __GetFv() method + # + # Get FV section contents and store its data into FV dictionary of self.Profile + # + # @param self The object pointer + # @retval True Successfully find a FV + # @retval False Not able to find a FV + # + def __GetFv(self): + if not self.__GetNextToken(): + return False + + S = self.__Token.upper() + if S.startswith("[") and not S.startswith("[FV."): + if not S.startswith("[CAPSULE.") \ + and not S.startswith("[VTF.") and not S.startswith("[RULE."): + raise Warning("Unknown section or section appear sequence error \n(The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.]) At Line ", self.FileName, self.CurrentLineNumber) + self.__UndoToken() + return False + + self.__UndoToken() + if not self.__IsToken("[FV.", True): + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ + % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) + raise Warning("Unknown Keyword At Line ", self.FileName, self.CurrentLineNumber) + + FvName = self.__GetUiName() + self.CurrentFvName = FvName.upper() + + if not self.__IsToken( "]"): + raise Warning("expected ']' At Line ", self.FileName, self.CurrentLineNumber) + + FvObj = CommonDataClass.FdfClass.FvClassObject() + FvObj.UiFvName = self.CurrentFvName + self.Profile.FvDict[self.CurrentFvName] = FvObj + + Status = self.__GetCreateFile(FvObj) + if not Status: + raise Warning("FV name error At Line ", self.FileName, self.CurrentLineNumber) + + self.__GetDefineStatements(FvObj) + + self.__GetAddressStatements(FvObj) + + self.__GetBlockStatement(FvObj) + + self.__GetSetStatements(FvObj) + + self.__GetFvAlignment(FvObj) + + self.__GetFvAttributes(FvObj) + + self.__GetFvNameGuid(FvObj) + + self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy()) + self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy()) + + while True: + isInf = self.__GetInfStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy()) + isFile = self.__GetFileStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy()) + if not isInf and not isFile: + break + + return True + + ## __GetFvAlignment() method + # + # Get alignment for FV + # + # @param self The object pointer + # @param Obj for whom alignment is got + # @retval True Successfully find a alignment statement + # @retval False Not able to find a alignment statement + # + def __GetFvAlignment(self, Obj): + + if not self.__IsKeyword( "FvAlignment"): + return False + + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected alignment value At Line ", self.FileName, self.CurrentLineNumber) + + if self.__Token.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \ + "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \ + "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \ + "1G", "2G"): + raise Warning("Unknown alignment value At Line ", self.FileName, self.CurrentLineNumber) + Obj.FvAlignment = self.__Token + return True + + ## __GetFvAttributes() method + # + # Get attributes for FV + # + # @param self The object pointer + # @param Obj for whom attribute is got + # @retval None + # + def __GetFvAttributes(self, FvObj): + + while self.__GetNextWord(): + name = self.__Token + if name not in ("ERASE_POLARITY", "MEMORY_MAPPED", \ + "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \ + "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \ + "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \ + "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \ + "WRITE_POLICY_RELIABLE"): + self.__UndoToken() + return + + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"): + raise Warning("expected TRUE/FALSE (1/0) At Line ", self.FileName, self.CurrentLineNumber) + + FvObj.FvAttributeDict[name] = self.__Token + + return + + ## __GetFvNameGuid() method + # + # Get FV GUID for FV + # + # @param self The object pointer + # @param Obj for whom GUID is got + # @retval None + # + def __GetFvNameGuid(self, FvObj): + + if not self.__IsKeyword( "FvNameGuid"): + return + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextGuid(): + raise Warning("expected FV GUID value", self.FileName, self.CurrentLineNumber) + + FvObj.FvNameGuid = self.__Token + + return + + ## __GetAprioriSection() method + # + # Get token statements + # + # @param self The object pointer + # @param FvObj for whom apriori is got + # @param MacroDict dictionary used to replace macro + # @retval True Successfully find apriori statement + # @retval False Not able to find apriori statement + # + def __GetAprioriSection(self, FvObj, MacroDict = {}): + + if not self.__IsKeyword( "APRIORI"): + return False + + if not self.__IsKeyword("PEI") and not self.__IsKeyword("DXE"): + raise Warning("expected Apriori file type At Line ", self.FileName, self.CurrentLineNumber) + AprType = self.__Token + + if not self.__IsToken( "{"): + raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber) + + AprSectionObj = CommonDataClass.FdfClass.AprioriSectionClassObject() + AprSectionObj.AprioriType = AprType + + self.__GetDefineStatements(AprSectionObj) + MacroDict.update(AprSectionObj.DefineVarDict) + + while True: + IsInf = self.__GetInfStatement( AprSectionObj, MacroDict = MacroDict) + IsFile = self.__GetFileStatement( AprSectionObj) + if not IsInf and not IsFile: + break + + if not self.__IsToken( "}"): + raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber) + + FvObj.AprioriSectionList.append(AprSectionObj) + return True + + ## __GetInfStatement() method + # + # Get INF statements + # + # @param self The object pointer + # @param Obj for whom inf statement is got + # @param MacroDict dictionary used to replace macro + # @retval True Successfully find inf statement + # @retval False Not able to find inf statement + # + def __GetInfStatement(self, Obj, ForCapsule = False, MacroDict = {}): + + if not self.__IsKeyword( "INF"): + return False + + ffsInf = CommonDataClass.FdfClass.FfsInfStatementClassObject() + self.__GetInfOptions( ffsInf) + + if not self.__GetNextToken(): + raise Warning("expected INF file path At Line ", self.FileName, self.CurrentLineNumber) + ffsInf.InfFileName = self.__Token + +# if ffsInf.InfFileName.find('$') >= 0: +# ffsInf.InfFileName = GenFdsGlobalVariable.GenFdsGlobalVariable.MacroExtend(ffsInf.InfFileName, MacroDict) + + if not ffsInf.InfFileName in self.Profile.InfList: + self.Profile.InfList.append(ffsInf.InfFileName) + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + self.Profile.InfFileLineList.append(FileLineTuple) + + if self.__IsToken('|'): + if self.__IsKeyword('RELOCS_STRIPPED'): + ffsInf.KeepReloc = False + elif self.__IsKeyword('RELOCS_RETAINED'): + ffsInf.KeepReloc = True + else: + raise Warning("Unknown reloc strip flag At Line ", self.FileName, self.CurrentLineNumber) + + if ForCapsule: + capsuleFfs = CapsuleData.CapsuleFfs() + capsuleFfs.Ffs = ffsInf + Obj.CapsuleDataList.append(capsuleFfs) + else: + Obj.FfsList.append(ffsInf) + return True + + ## __GetInfOptions() method + # + # Get options for INF + # + # @param self The object pointer + # @param FfsInfObj for whom option is got + # + def __GetInfOptions(self, FfsInfObj): + + if self.__IsKeyword( "RuleOverride"): + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected Rule name At Line ", self.FileName, self.CurrentLineNumber) + FfsInfObj.Rule = self.__Token + + if self.__IsKeyword( "VERSION"): + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected Version At Line ", self.FileName, self.CurrentLineNumber) + + if self.__GetStringData(): + FfsInfObj.Version = self.__Token + + if self.__IsKeyword( "UI"): + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected UI name At Line ", self.FileName, self.CurrentLineNumber) + + if self.__GetStringData(): + FfsInfObj.Ui = self.__Token + + if self.__IsKeyword( "USE"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected ARCH name", self.FileName, self.CurrentLineNumber) + FfsInfObj.UseArch = self.__Token + + + if self.__GetNextToken(): + p = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)') + if p.match(self.__Token): + FfsInfObj.KeyStringList.append(self.__Token) + if not self.__IsToken(","): + return + else: + self.__UndoToken() + return + + while self.__GetNextToken(): + if not p.match(self.__Token): + raise Warning("expected KeyString \"Target_Tag_Arch\" At Line ", self.FileName, self.CurrentLineNumber) + FfsInfObj.KeyStringList.append(self.__Token) + + if not self.__IsToken(","): + break + + ## __GetFileStatement() method + # + # Get FILE statements + # + # @param self The object pointer + # @param Obj for whom FILE statement is got + # @param MacroDict dictionary used to replace macro + # @retval True Successfully find FILE statement + # @retval False Not able to find FILE statement + # + def __GetFileStatement(self, Obj, ForCapsule = False, MacroDict = {}): + + if not self.__IsKeyword( "FILE"): + return False + + FfsFileObj = CommonDataClass.FdfClass.FileStatementClassObject() + + if not self.__GetNextWord(): + raise Warning("expected FFS type At Line ", self.FileName, self.CurrentLineNumber) + FfsFileObj.FvFileType = self.__Token + + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextGuid(): + if not self.__GetNextWord(): + raise Warning("expected File GUID", self.FileName, self.CurrentLineNumber) + if self.__Token == 'PCD': + if not self.__IsToken( "("): + raise Warning("expected '('", self.FileName, self.CurrentLineNumber) + PcdPair = self.__GetNextPcdName() + if not self.__IsToken( ")"): + raise Warning("expected ')'", self.FileName, self.CurrentLineNumber) + self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')' + + FfsFileObj.NameGuid = self.__Token + + self.__GetFilePart( FfsFileObj, MacroDict.copy()) + + if ForCapsule: + capsuleFfs = CapsuleData.CapsuleFfs() + capsuleFfs.Ffs = FfsFileObj + Obj.CapsuleDataList.append(capsuleFfs) + else: + Obj.FfsList.append(FfsFileObj) + + return True + + ## __FileCouldHaveRelocFlag() method + # + # Check whether reloc strip flag can be set for a file type. + # + # @param self The object pointer + # @param FileType The file type to check with + # @retval True This type could have relocation strip flag + # @retval False No way to have it + # + + def __FileCouldHaveRelocFlag (self, FileType): + if FileType in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'): + return True + else: + return False + + ## __SectionCouldHaveRelocFlag() method + # + # Check whether reloc strip flag can be set for a section type. + # + # @param self The object pointer + # @param SectionType The section type to check with + # @retval True This type could have relocation strip flag + # @retval False No way to have it + # + + def __SectionCouldHaveRelocFlag (self, SectionType): + if SectionType in ('TE', 'PE32'): + return True + else: + return False + + ## __GetFilePart() method + # + # Get components for FILE statement + # + # @param self The object pointer + # @param FfsFileObj for whom component is got + # @param MacroDict dictionary used to replace macro + # + def __GetFilePart(self, FfsFileObj, MacroDict = {}): + + self.__GetFileOpts( FfsFileObj) + + if not self.__IsToken("{"): +# if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'): +# if self.__FileCouldHaveRelocFlag(FfsFileObj.FvFileType): +# if self.__Token == 'RELOCS_STRIPPED': +# FfsFileObj.KeepReloc = False +# else: +# FfsFileObj.KeepReloc = True +# else: +# raise Warning("File type %s could not have reloc strip flag At Line %d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) +# +# if not self.__IsToken("{"): + raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected File name or section data At Line ", self.FileName, self.CurrentLineNumber) + + if self.__Token == "FV": + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected FV name At Line ", self.FileName, self.CurrentLineNumber) + FfsFileObj.FvName = self.__Token + + elif self.__Token == "FD": + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected FD name At Line ", self.FileName, self.CurrentLineNumber) + FfsFileObj.FdName = self.__Token + + elif self.__Token in ("DEFINE", "APRIORI", "SECTION"): + self.__UndoToken() + self.__GetSectionData( FfsFileObj, MacroDict) + else: + FfsFileObj.FileName = self.__Token + + if not self.__IsToken( "}"): + raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber) + + ## __GetFileOpts() method + # + # Get options for FILE statement + # + # @param self The object pointer + # @param FfsFileObj for whom options is got + # + def __GetFileOpts(self, FfsFileObj): + + if self.__GetNextToken(): + Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)') + if Pattern.match(self.__Token): + FfsFileObj.KeyStringList.append(self.__Token) + if self.__IsToken(","): + while self.__GetNextToken(): + if not Pattern.match(self.__Token): + raise Warning("expected KeyString \"Target_Tag_Arch\" At Line ", self.FileName, self.CurrentLineNumber) + FfsFileObj.KeyStringList.append(self.__Token) + + if not self.__IsToken(","): + break + + else: + self.__UndoToken() + + if self.__IsKeyword( "FIXED", True): + FfsFileObj.Fixed = True + + if self.__IsKeyword( "CHECKSUM", True): + FfsFileObj.CheckSum = True + + if self.__GetAlignment(): + FfsFileObj.Alignment = self.__Token + + + + ## __GetAlignment() method + # + # Return the alignment value + # + # @param self The object pointer + # @retval True Successfully find alignment + # @retval False Not able to find alignment + # + def __GetAlignment(self): + if self.__IsKeyword( "Align", True): + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected alignment value At Line ", self.FileName, self.CurrentLineNumber) + return True + + return False + + ## __GetFilePart() method + # + # Get section data for FILE statement + # + # @param self The object pointer + # @param FfsFileObj for whom section is got + # @param MacroDict dictionary used to replace macro + # + def __GetSectionData(self, FfsFileObj, MacroDict = {}): + Dict = {} + Dict.update(MacroDict) + + self.__GetDefineStatements(FfsFileObj) + + Dict.update(FfsFileObj.DefineVarDict) + self.__GetAprioriSection(FfsFileObj, Dict.copy()) + self.__GetAprioriSection(FfsFileObj, Dict.copy()) + + while True: + IsLeafSection = self.__GetLeafSection(FfsFileObj, Dict) + IsEncapSection = self.__GetEncapsulationSec(FfsFileObj) + if not IsLeafSection and not IsEncapSection: + break + + ## __GetLeafSection() method + # + # Get leaf section for Obj + # + # @param self The object pointer + # @param Obj for whom leaf section is got + # @param MacroDict dictionary used to replace macro + # @retval True Successfully find section statement + # @retval False Not able to find section statement + # + def __GetLeafSection(self, Obj, MacroDict = {}): + + OldPos = self.GetFileBufferPos() + + if not self.__IsKeyword( "SECTION"): + if len(Obj.SectionList) == 0: + raise Warning("expected SECTION At Line ", self.FileName, self.CurrentLineNumber) + else: + return False + + AlignValue = None + if self.__GetAlignment(): + AlignValue = self.__Token + + BuildNum = None + if self.__IsKeyword( "BUILD_NUM"): + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Build number value At Line ", self.FileName, self.CurrentLineNumber) + + BuildNum = self.__Token + + if self.__IsKeyword( "VERSION"): + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected version At Line ", self.FileName, self.CurrentLineNumber) + VerSectionObj = CommonDataClass.FdfClass.VerSectionClassObject() + VerSectionObj.Alignment = AlignValue + VerSectionObj.BuildNum = BuildNum + if self.__GetStringData(): + VerSectionObj.StringData = self.__Token + else: + VerSectionObj.FileName = self.__Token + Obj.SectionList.append(VerSectionObj) + + elif self.__IsKeyword( "UI"): + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected UI At Line ", self.FileName, self.CurrentLineNumber) + UiSectionObj = CommonDataClass.FdfClass.UiSectionClassObject() + UiSectionObj.Alignment = AlignValue + if self.__GetStringData(): + UiSectionObj.StringData = self.__Token + else: + UiSectionObj.FileName = self.__Token + Obj.SectionList.append(UiSectionObj) + + elif self.__IsKeyword( "FV_IMAGE"): + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + if not self.__GetNextWord(): + raise Warning("expected FV name At Line ", self.FileName, self.CurrentLineNumber) + + FvName = self.__Token.upper() + FvObj = None + + if self.__IsToken( "{"): + FvObj = Fv.FV() + FvObj.UiFvName = FvName + self.__GetDefineStatements(FvObj) + MacroDict.update(FvObj.DefineVarDict) + self.__GetBlockStatement(FvObj) + self.__GetSetStatements(FvObj) + self.__GetFvAlignment(FvObj) + self.__GetFvAttributes(FvObj) + self.__GetAprioriSection(FvObj, MacroDict.copy()) + self.__GetAprioriSection(FvObj, MacroDict.copy()) + + while True: + IsInf = self.__GetInfStatement(FvObj, MacroDict.copy()) + IsFile = self.__GetFileStatement(FvObj, MacroDict.copy()) + if not IsInf and not IsFile: + break + + if not self.__IsToken( "}"): + raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber) + + FvImageSectionObj = CommonDataClass.FdfClass.FvImageSectionClassObject() + FvImageSectionObj.Alignment = AlignValue + if FvObj != None: + FvImageSectionObj.Fv = FvObj + FvImageSectionObj.FvName = None + else: + FvImageSectionObj.FvName = FvName + + Obj.SectionList.append(FvImageSectionObj) + + elif self.__IsKeyword("PEI_DEPEX_EXP") or self.__IsKeyword("DXE_DEPEX_EXP"): + DepexSectionObj = CommonDataClass.FdfClass.DepexSectionClassObject() + DepexSectionObj.Alignment = AlignValue + DepexSectionObj.DepexType = self.__Token + + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + if not self.__IsToken( "{"): + raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber) + if not self.__SkipToToken( "}"): + raise Warning("expected Depex expression ending '}' At Line ", self.FileName, self.CurrentLineNumber) + + DepexSectionObj.Expression = self.__SkippedChars.rstrip('}') + Obj.SectionList.append(DepexSectionObj) + + else: + + if not self.__GetNextWord(): + raise Warning("expected section type At Line ", self.FileName, self.CurrentLineNumber) + + # Encapsulation section appear, UndoToken and return + if self.__Token == "COMPRESS" or self.__Token == "GUIDED": + self.SetFileBufferPos(OldPos) + return False + + if self.__Token not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\ + "UI", "VERSION", "PEI_DEPEX", "SUBTYPE_GUID", "SMM_DEPEX"): + raise Warning("Unknown section type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + # DataSection + DataSectionObj = CommonDataClass.FdfClass.DataSectionClassObject() + DataSectionObj.Alignment = AlignValue + DataSectionObj.SecType = self.__Token + + if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'): + if self.__FileCouldHaveRelocFlag(Obj.FvFileType) and self.__SectionCouldHaveRelocFlag(DataSectionObj.SecType): + if self.__Token == 'RELOCS_STRIPPED': + DataSectionObj.KeepReloc = False + else: + DataSectionObj.KeepReloc = True + else: + raise Warning("File type %s, section type %s, could not have reloc strip flag At Line %d" % (Obj.FvFileType, DataSectionObj.SecType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + + if self.__IsToken("="): + if not self.__GetNextToken(): + raise Warning("expected section file path At Line ", self.FileName, self.CurrentLineNumber) + DataSectionObj.SectFileName = self.__Token + else: + if not self.__GetCglSection(DataSectionObj): + return False + + Obj.SectionList.append(DataSectionObj) + + return True + + ## __GetCglSection() method + # + # Get compressed or GUIDed section for Obj + # + # @param self The object pointer + # @param Obj for whom leaf section is got + # @param AlignValue alignment value for complex section + # @retval True Successfully find section statement + # @retval False Not able to find section statement + # + def __GetCglSection(self, Obj, AlignValue = None): + + if self.__IsKeyword( "COMPRESS"): + type = "PI_STD" + if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"): + type = self.__Token + + if not self.__IsToken("{"): + raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber) + + CompressSectionObj = CommonDataClass.FdfClass.CompressSectionClassObject() + CompressSectionObj.Alignment = AlignValue + CompressSectionObj.CompType = type + # Recursive sections... + while True: + IsLeafSection = self.__GetLeafSection(CompressSectionObj) + IsEncapSection = self.__GetEncapsulationSec(CompressSectionObj) + if not IsLeafSection and not IsEncapSection: + break + + + if not self.__IsToken( "}"): + raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber) + Obj.SectionList.append(CompressSectionObj) + +# else: +# raise Warning("Compress type not known At Line ") + + return True + + elif self.__IsKeyword( "GUIDED"): + GuidValue = None + if self.__GetNextGuid(): + GuidValue = self.__Token + + AttribDict = self.__GetGuidAttrib() + if not self.__IsToken("{"): + raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber) + GuidSectionObj = CommonDataClass.FdfClass.GuidSectionClassObject() + GuidSectionObj.Alignment = AlignValue + GuidSectionObj.NameGuid = GuidValue + GuidSectionObj.SectionType = "GUIDED" + GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"] + GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"] + # Recursive sections... + while True: + IsLeafSection = self.__GetLeafSection(GuidSectionObj) + IsEncapSection = self.__GetEncapsulationSec(GuidSectionObj) + if not IsLeafSection and not IsEncapSection: + break + + if not self.__IsToken( "}"): + raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber) + Obj.SectionList.append(GuidSectionObj) + + return True + + return False + + ## __GetGuidAttri() method + # + # Get attributes for GUID section + # + # @param self The object pointer + # @retval AttribDict Dictionary of key-value pair of section attributes + # + def __GetGuidAttrib(self): + + AttribDict = {} + AttribDict["PROCESSING_REQUIRED"] = False + AttribDict["AUTH_STATUS_VALID"] = False + if self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID"): + AttribKey = self.__Token + + if not self.__IsToken("="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"): + raise Warning("expected TRUE/FALSE (1/0) At Line ", self.FileName, self.CurrentLineNumber) + AttribDict[AttribKey] = self.__Token + + if self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID"): + AttribKey = self.__Token + + if not self.__IsToken("="): + raise Warning("expected '=' At Line ") + + if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"): + raise Warning("expected TRUE/FALSE (1/0) At Line ", self.FileName, self.CurrentLineNumber) + AttribDict[AttribKey] = self.__Token + + return AttribDict + + ## __GetEncapsulationSec() method + # + # Get encapsulation section for FILE + # + # @param self The object pointer + # @param FfsFile for whom section is got + # @retval True Successfully find section statement + # @retval False Not able to find section statement + # + def __GetEncapsulationSec(self, FfsFileObj): + + OldPos = self.GetFileBufferPos() + if not self.__IsKeyword( "SECTION"): + if len(FfsFileObj.SectionList) == 0: + raise Warning("expected SECTION At Line ", self.FileName, self.CurrentLineNumber) + else: + return False + + AlignValue = None + if self.__GetAlignment(): + AlignValue = self.__Token + + if not self.__GetCglSection(FfsFileObj, AlignValue): + self.SetFileBufferPos(OldPos) + return False + else: + return True + + ## __GetCapsule() method + # + # Get capsule section contents and store its data into capsule list of self.Profile + # + # @param self The object pointer + # @retval True Successfully find a capsule + # @retval False Not able to find a capsule + # + def __GetCapsule(self): + + if not self.__GetNextToken(): + return False + + S = self.__Token.upper() + if S.startswith("[") and not S.startswith("[CAPSULE."): + if not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."): + raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber) + self.__UndoToken() + return False + + self.__UndoToken() + if not self.__IsToken("[CAPSULE.", True): + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ + % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) + raise Warning("expected [Capsule.] At Line ", self.FileName, self.CurrentLineNumber) + + CapsuleObj = CommonDataClass.FdfClass.CapsuleClassObject() + + CapsuleName = self.__GetUiName() + if not CapsuleName: + raise Warning("expected capsule name At line ", self.FileName, self.CurrentLineNumber) + + CapsuleObj.UiCapsuleName = CapsuleName.upper() + + if not self.__IsToken( "]"): + raise Warning("expected ']' At Line ", self.FileName, self.CurrentLineNumber) + + if self.__IsKeyword("CREATE_FILE"): + if not self.__IsToken( "="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected file name At Line ", self.FileName, self.CurrentLineNumber) + + CapsuleObj.CreateFile = self.__Token + + self.__GetCapsuleStatements(CapsuleObj) + self.Profile.CapsuleList.append(CapsuleObj) + return True + + ## __GetCapsuleStatements() method + # + # Get statements for capsule + # + # @param self The object pointer + # @param Obj for whom statements are got + # + def __GetCapsuleStatements(self, Obj): + self.__GetCapsuleTokens(Obj) + self.__GetDefineStatements(Obj) + self.__GetSetStatements(Obj) + + self.__GetCapsuleData(Obj) + + ## __GetCapsuleStatements() method + # + # Get token statements for capsule + # + # @param self The object pointer + # @param Obj for whom token statements are got + # + def __GetCapsuleTokens(self, Obj): + + if not self.__IsKeyword("CAPSULE_GUID"): + raise Warning("expected 'CAPSULE_GUID' At Line ", self.FileName, self.CurrentLineNumber) + + while self.__CurrentLine().find("=") != -1: + NameValue = self.__CurrentLine().split("=") + Obj.TokensDict[NameValue[0].strip()] = NameValue[1].strip() + self.CurrentLineNumber += 1 + self.CurrentOffsetWithinLine = 0 + + ## __GetCapsuleData() method + # + # Get capsule data for capsule + # + # @param self The object pointer + # @param Obj for whom capsule data are got + # + def __GetCapsuleData(self, Obj): + + while True: + IsInf = self.__GetInfStatement(Obj, True) + IsFile = self.__GetFileStatement(Obj, True) + IsFv = self.__GetFvStatement(Obj) + if not IsInf and not IsFile and not IsFv: + break + + ## __GetFvStatement() method + # + # Get FV for capsule + # + # @param self The object pointer + # @param CapsuleObj for whom FV is got + # @retval True Successfully find a FV statement + # @retval False Not able to find a FV statement + # + def __GetFvStatement(self, CapsuleObj): + + if not self.__IsKeyword("FV"): + return False + + if not self.__IsToken("="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected FV name At Line ", self.FileName, self.CurrentLineNumber) + +# CapsuleFv = CapsuleData.CapsuleFv() +# CapsuleFv.FvName = self.__Token +# CapsuleObj.CapsuleDataList.append(CapsuleFv) + return True + + ## __GetRule() method + # + # Get Rule section contents and store its data into rule list of self.Profile + # + # @param self The object pointer + # @retval True Successfully find a Rule + # @retval False Not able to find a Rule + # + def __GetRule(self): + + if not self.__GetNextToken(): + return False + + S = self.__Token.upper() + if S.startswith("[") and not S.startswith("[RULE."): + if not S.startswith("[OPTIONROM."): + raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber) + self.__UndoToken() + return False + self.__UndoToken() + if not self.__IsToken("[Rule.", True): + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ + % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) + raise Warning("expected [Rule.] At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__SkipToToken("."): + raise Warning("expected '.' At Line ", self.FileName, self.CurrentLineNumber) + + Arch = self.__SkippedChars.rstrip(".") + if Arch.upper() not in ("IA32", "X64", "IPF", "EBC", "ARM", "COMMON"): + raise Warning("Unknown Arch At line ", self.FileName, self.CurrentLineNumber) + + ModuleType = self.__GetModuleType() + + TemplateName = "" + if self.__IsToken("."): + if not self.__GetNextWord(): + raise Warning("expected template name At Line ", self.FileName, self.CurrentLineNumber) + TemplateName = self.__Token + + if not self.__IsToken( "]"): + raise Warning("expected ']' At Line ", self.FileName, self.CurrentLineNumber) + + RuleObj = self.__GetRuleFileStatements() + RuleObj.Arch = Arch.upper() + RuleObj.ModuleType = ModuleType + RuleObj.TemplateName = TemplateName + if TemplateName == '' : + self.Profile.RuleDict['RULE' + \ + '.' + \ + Arch.upper() + \ + '.' + \ + ModuleType.upper() ] = RuleObj + else : + self.Profile.RuleDict['RULE' + \ + '.' + \ + Arch.upper() + \ + '.' + \ + ModuleType.upper() + \ + '.' + \ + TemplateName.upper() ] = RuleObj +# self.Profile.RuleList.append(rule) + return True + + ## __GetModuleType() method + # + # Return the module type + # + # @param self The object pointer + # @retval string module type + # + def __GetModuleType(self): + + if not self.__GetNextWord(): + raise Warning("expected Module type At Line ", self.FileName, self.CurrentLineNumber) + if self.__Token.upper() not in ("SEC", "PEI_CORE", "PEIM", "DXE_CORE", \ + "DXE_DRIVER", "DXE_SAL_DRIVER", \ + "DXE_SMM_DRIVER", "DXE_RUNTIME_DRIVER", \ + "UEFI_DRIVER", "UEFI_APPLICATION", "USER_DEFINED", "DEFAULT", "BASE", \ + "SECURITY_CORE", "COMBINED_PEIM_DRIVER", "PIC_PEIM", "RELOCATABLE_PEIM", \ + "PE32_PEIM", "BS_DRIVER", "RT_DRIVER", "SAL_RT_DRIVER", "APPLICATION"): + raise Warning("Unknown Module type At line ", self.FileName, self.CurrentLineNumber) + return self.__Token + + ## __GetFileExtension() method + # + # Return the file extension + # + # @param self The object pointer + # @retval string file name extension + # + def __GetFileExtension(self): + if not self.__IsToken("."): + raise Warning("expected '.' At Line ", self.FileName, self.CurrentLineNumber) + + Ext = "" + if self.__GetNextToken(): + Pattern = re.compile(r'([a-zA-Z][a-zA-Z0-9]*)') + if Pattern.match(self.__Token): + Ext = self.__Token + return '.' + Ext + else: + raise Warning("Unknown file extension At Line ", self.FileName, self.CurrentLineNumber) + + else: + raise Warning("expected file extension At Line ", self.FileName, self.CurrentLineNumber) + + ## __GetRuleFileStatement() method + # + # Get rule contents + # + # @param self The object pointer + # @retval Rule Rule object + # + def __GetRuleFileStatements(self): + + if not self.__IsKeyword("FILE"): + raise Warning("expected FILE At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextWord(): + raise Warning("expected FV type At Line ", self.FileName, self.CurrentLineNumber) + + Type = self.__Token.strip().upper() + if Type not in ("RAW", "FREEFORM", "SEC", "PEI_CORE", "PEIM",\ + "PEI_DXE_COMBO", "DRIVER", "DXE_CORE", "APPLICATION", "FV_IMAGE"): + raise Warning("Unknown FV type At line ", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__IsKeyword("$(NAMED_GUID)"): + if not self.__GetNextWord(): + raise Warning("expected $(NAMED_GUID)", self.FileName, self.CurrentLineNumber) + if self.__Token == 'PCD': + if not self.__IsToken( "("): + raise Warning("expected '('", self.FileName, self.CurrentLineNumber) + PcdPair = self.__GetNextPcdName() + if not self.__IsToken( ")"): + raise Warning("expected ')'", self.FileName, self.CurrentLineNumber) + self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')' + + NameGuid = self.__Token + + KeepReloc = None + if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'): + if self.__FileCouldHaveRelocFlag(Type): + if self.__Token == 'RELOCS_STRIPPED': + KeepReloc = False + else: + KeepReloc = True + else: + raise Warning("File type %s could not have reloc strip flag At Line %d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + + KeyStringList = [] + if self.__GetNextToken(): + Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)') + if Pattern.match(self.__Token): + KeyStringList.append(self.__Token) + if self.__IsToken(","): + while self.__GetNextToken(): + if not Pattern.match(self.__Token): + raise Warning("expected KeyString \"Target_Tag_Arch\" At Line ", self.FileName, self.CurrentLineNumber) + KeyStringList.append(self.__Token) + + if not self.__IsToken(","): + break + + else: + self.__UndoToken() + + + Fixed = False + if self.__IsKeyword("Fixed", True): + Fixed = True + + CheckSum = False + if self.__IsKeyword("CheckSum", True): + CheckSum = True + + AlignValue = "" + if self.__GetAlignment(): + if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): + raise Warning("Incorrect alignment At Line ", self.FileName, self.CurrentLineNumber) + AlignValue = self.__Token + + if self.__IsToken("{"): + # Complex file rule expected + Rule = RuleComplexFile.RuleComplexFile() + Rule.FvFileType = Type + Rule.NameGuid = NameGuid + Rule.Alignment = AlignValue + Rule.CheckSum = CheckSum + Rule.Fixed = Fixed + Rule.KeyStringList = KeyStringList + if KeepReloc != None: + Rule.KeepReloc = KeepReloc + + while True: + IsEncapsulate = self.__GetRuleEncapsulationSection(Rule) + IsLeaf = self.__GetEfiSection(Rule) + if not IsEncapsulate and not IsLeaf: + break + + if not self.__IsToken("}"): + raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber) + + return Rule + + elif self.__IsToken("|"): + # Ext rule expected + Ext = self.__GetFileExtension() + + Rule = RuleSimpleFile.RuleSimpleFile() + + Rule.FvFileType = Type + Rule.NameGuid = NameGuid + Rule.Alignment = AlignValue + Rule.CheckSum = CheckSum + Rule.Fixed = Fixed + Rule.FileExtension = Ext + Rule.KeyStringList = KeyStringList + if KeepReloc != None: + Rule.KeepReloc = KeepReloc + + return Rule + + else: + # Simple file rule expected + if not self.__GetNextWord(): + raise Warning("expected leaf section type At Line ", self.FileName, self.CurrentLineNumber) + + SectionName = self.__Token + + if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\ + "UI", "PEI_DEPEX", "VERSION", "SUBTYPE_GUID", "SMM_DEPEX"): + raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber) + + + if self.__IsKeyword("Fixed", True): + Fixed = True + + if self.__IsKeyword("CheckSum", True): + CheckSum = True + + if self.__GetAlignment(): + if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): + raise Warning("Incorrect alignment At Line ", self.FileName, self.CurrentLineNumber) + AlignValue = self.__Token + + if not self.__GetNextToken(): + raise Warning("expected File name At Line ", self.FileName, self.CurrentLineNumber) + + Rule = RuleSimpleFile.RuleSimpleFile() + Rule.SectionType = SectionName + Rule.FvFileType = Type + Rule.NameGuid = NameGuid + Rule.Alignment = AlignValue + Rule.CheckSum = CheckSum + Rule.Fixed = Fixed + Rule.FileName = self.__Token + Rule.KeyStringList = KeyStringList + if KeepReloc != None: + Rule.KeepReloc = KeepReloc + return Rule + + ## __GetEfiSection() method + # + # Get section list for Rule + # + # @param self The object pointer + # @param Obj for whom section is got + # @retval True Successfully find section statement + # @retval False Not able to find section statement + # + def __GetEfiSection(self, Obj): + + OldPos = self.GetFileBufferPos() + if not self.__GetNextWord(): + return False + SectionName = self.__Token + + if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\ + "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"): + self.__UndoToken() + return False + + if SectionName == "FV_IMAGE": + FvImageSectionObj = FvImageSection.FvImageSection() + if self.__IsKeyword("FV_IMAGE"): + pass + if self.__IsToken( "{"): + FvObj = Fv.FV() + self.__GetDefineStatements(FvObj) + self.__GetBlockStatement(FvObj) + self.__GetSetStatements(FvObj) + self.__GetFvAlignment(FvObj) + self.__GetFvAttributes(FvObj) + self.__GetAprioriSection(FvObj) + self.__GetAprioriSection(FvObj) + + while True: + IsInf = self.__GetInfStatement(FvObj) + IsFile = self.__GetFileStatement(FvObj) + if not IsInf and not IsFile: + break + + if not self.__IsToken( "}"): + raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber) + FvImageSectionObj.Fv = FvObj + FvImageSectionObj.FvName = None + + else: + if not self.__IsKeyword("FV"): + raise Warning("expected 'FV' At Line ", self.FileName, self.CurrentLineNumber) + FvImageSectionObj.FvFileType = self.__Token + + if self.__GetAlignment(): + if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): + raise Warning("Incorrect alignment At Line ", self.FileName, self.CurrentLineNumber) + FvImageSectionObj.Alignment = self.__Token + + if self.__IsKeyword("FV"): + FvImageSectionObj.FvFileType = self.__Token + + if self.__GetAlignment(): + if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): + raise Warning("Incorrect alignment At Line ", self.FileName, self.CurrentLineNumber) + FvImageSectionObj.Alignment = self.__Token + + if self.__IsToken('|'): + FvImageSectionObj.FvFileExtension = self.__GetFileExtension() + elif self.__GetNextToken(): + if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\ + "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"): + FvImageSectionObj.FvFileName = self.__Token + else: + self.__UndoToken() + else: + raise Warning("expected FV file name At Line ", self.FileName, self.CurrentLineNumber) + + Obj.SectionList.append(FvImageSectionObj) + return True + + EfiSectionObj = EfiSection.EfiSection() + EfiSectionObj.SectionType = SectionName + + if not self.__GetNextToken(): + raise Warning("expected file type At Line ", self.FileName, self.CurrentLineNumber) + + if self.__Token == "STRING": + if not self.__RuleSectionCouldHaveString(EfiSectionObj.SectionType): + raise Warning("%s section could NOT have string data At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + + if not self.__IsToken('='): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Quoted String At Line ", self.FileName, self.CurrentLineNumber) + + if self.__GetStringData(): + EfiSectionObj.StringData = self.__Token + + if self.__IsKeyword("BUILD_NUM"): + if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType): + raise Warning("%s section could NOT have BUILD_NUM At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected Build number At Line ", self.FileName, self.CurrentLineNumber) + EfiSectionObj.BuildNum = self.__Token + + else: + EfiSectionObj.FileType = self.__Token + self.__CheckRuleSectionFileType(EfiSectionObj.SectionType, EfiSectionObj.FileType) + + if self.__IsKeyword("Optional"): + if not self.__RuleSectionCouldBeOptional(EfiSectionObj.SectionType): + raise Warning("%s section could NOT be optional At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + EfiSectionObj.Optional = True + + if self.__IsKeyword("BUILD_NUM"): + if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType): + raise Warning("%s section could NOT have BUILD_NUM At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected Build number At Line ", self.FileName, self.CurrentLineNumber) + EfiSectionObj.BuildNum = self.__Token + + if self.__GetAlignment(): + EfiSectionObj.Alignment = self.__Token + + if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'): + if self.__SectionCouldHaveRelocFlag(EfiSectionObj.SectionType): + if self.__Token == 'RELOCS_STRIPPED': + EfiSectionObj.KeepReloc = False + else: + EfiSectionObj.KeepReloc = True + if Obj.KeepReloc != None and Obj.KeepReloc != EfiSectionObj.KeepReloc: + raise Warning("Section type %s has reloc strip flag conflict with Rule At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + else: + raise Warning("Section type %s could not have reloc strip flag At Line %d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + + + if self.__IsToken('|'): + EfiSectionObj.FileExtension = self.__GetFileExtension() + elif self.__GetNextToken(): + if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\ + "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"): + + if self.__Token.startswith('PCD'): + self.__UndoToken() + self.__GetNextWord() + + if self.__Token == 'PCD': + if not self.__IsToken( "("): + raise Warning("expected '('", self.FileName, self.CurrentLineNumber) + PcdPair = self.__GetNextPcdName() + if not self.__IsToken( ")"): + raise Warning("expected ')'", self.FileName, self.CurrentLineNumber) + self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')' + + EfiSectionObj.FileName = self.__Token + + else: + self.__UndoToken() + else: + raise Warning("expected section file name At Line ", self.FileName, self.CurrentLineNumber) + + Obj.SectionList.append(EfiSectionObj) + return True + + ## __RuleSectionCouldBeOptional() method + # + # Get whether a section could be optional + # + # @param self The object pointer + # @param SectionType The section type to check + # @retval True section could be optional + # @retval False section never optional + # + def __RuleSectionCouldBeOptional(self, SectionType): + if SectionType in ("DXE_DEPEX", "UI", "VERSION", "PEI_DEPEX", "RAW", "SMM_DEPEX"): + return True + else: + return False + + ## __RuleSectionCouldHaveBuildNum() method + # + # Get whether a section could have build number information + # + # @param self The object pointer + # @param SectionType The section type to check + # @retval True section could have build number information + # @retval False section never have build number information + # + def __RuleSectionCouldHaveBuildNum(self, SectionType): + if SectionType in ("VERSION"): + return True + else: + return False + + ## __RuleSectionCouldHaveString() method + # + # Get whether a section could have string + # + # @param self The object pointer + # @param SectionType The section type to check + # @retval True section could have string + # @retval False section never have string + # + def __RuleSectionCouldHaveString(self, SectionType): + if SectionType in ("UI", "VERSION"): + return True + else: + return False + + ## __CheckRuleSectionFileType() method + # + # Get whether a section matches a file type + # + # @param self The object pointer + # @param SectionType The section type to check + # @param FileType The file type to check + # + def __CheckRuleSectionFileType(self, SectionType, FileType): + if SectionType == "COMPAT16": + if FileType not in ("COMPAT16", "SEC_COMPAT16"): + raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber) + elif SectionType == "PE32": + if FileType not in ("PE32", "SEC_PE32"): + raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber) + elif SectionType == "PIC": + if FileType not in ("PIC", "PIC"): + raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber) + elif SectionType == "TE": + if FileType not in ("TE", "SEC_TE"): + raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber) + elif SectionType == "RAW": + if FileType not in ("BIN", "SEC_BIN", "RAW", "ASL", "ACPI"): + raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber) + elif SectionType == "DXE_DEPEX": + if FileType not in ("DXE_DEPEX", "SEC_DXE_DEPEX"): + raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber) + elif SectionType == "UI": + if FileType not in ("UI", "SEC_UI"): + raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber) + elif SectionType == "VERSION": + if FileType not in ("VERSION", "SEC_VERSION"): + raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber) + elif SectionType == "PEI_DEPEX": + if FileType not in ("PEI_DEPEX", "SEC_PEI_DEPEX"): + raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber) + elif SectionType == "GUID": + if FileType not in ("PE32", "SEC_GUID"): + raise Warning("Incorrect section file type At Line ", self.FileName, self.CurrentLineNumber) + + ## __GetRuleEncapsulationSection() method + # + # Get encapsulation section for Rule + # + # @param self The object pointer + # @param Rule for whom section is got + # @retval True Successfully find section statement + # @retval False Not able to find section statement + # + def __GetRuleEncapsulationSection(self, Rule): + + if self.__IsKeyword( "COMPRESS"): + Type = "PI_STD" + if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"): + Type = self.__Token + + if not self.__IsToken("{"): + raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber) + + CompressSectionObj = CompressSection.CompressSection() + + CompressSectionObj.CompType = Type + # Recursive sections... + while True: + IsEncapsulate = self.__GetRuleEncapsulationSection(CompressSectionObj) + IsLeaf = self.__GetEfiSection(CompressSectionObj) + if not IsEncapsulate and not IsLeaf: + break + + if not self.__IsToken( "}"): + raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber) + Rule.SectionList.append(CompressSectionObj) + + return True + + elif self.__IsKeyword( "GUIDED"): + GuidValue = None + if self.__GetNextGuid(): + GuidValue = self.__Token + + if self.__IsKeyword( "$(NAMED_GUID)"): + GuidValue = self.__Token + + AttribDict = self.__GetGuidAttrib() + + if not self.__IsToken("{"): + raise Warning("expected '{' At Line ", self.FileName, self.CurrentLineNumber) + GuidSectionObj = GuidSection.GuidSection() + GuidSectionObj.NameGuid = GuidValue + GuidSectionObj.SectionType = "GUIDED" + GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"] + GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"] + + # Efi sections... + while True: + IsEncapsulate = self.__GetRuleEncapsulationSection(GuidSectionObj) + IsLeaf = self.__GetEfiSection(GuidSectionObj) + if not IsEncapsulate and not IsLeaf: + break + + if not self.__IsToken( "}"): + raise Warning("expected '}' At Line ", self.FileName, self.CurrentLineNumber) + Rule.SectionList.append(GuidSectionObj) + + return True + + return False + + ## __GetVtf() method + # + # Get VTF section contents and store its data into VTF list of self.Profile + # + # @param self The object pointer + # @retval True Successfully find a VTF + # @retval False Not able to find a VTF + # + def __GetVtf(self): + + if not self.__GetNextToken(): + return False + + S = self.__Token.upper() + if S.startswith("[") and not S.startswith("[VTF."): + if not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."): + raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber) + self.__UndoToken() + return False + + self.__UndoToken() + if not self.__IsToken("[VTF.", True): + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ + % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) + raise Warning("expected [VTF.] At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__SkipToToken("."): + raise Warning("expected '.' At Line ", self.FileName, self.CurrentLineNumber) + + Arch = self.__SkippedChars.rstrip(".").upper() + if Arch not in ("IA32", "X64", "IPF", "ARM"): + raise Warning("Unknown Arch At line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextWord(): + raise Warning("expected VTF name At Line ", self.FileName, self.CurrentLineNumber) + Name = self.__Token.upper() + + VtfObj = Vtf.Vtf() + VtfObj.UiName = Name + VtfObj.KeyArch = Arch + + if self.__IsToken(","): + if not self.__GetNextWord(): + raise Warning("expected Arch list At Line ", self.FileName, self.CurrentLineNumber) + if self.__Token.upper() not in ("IA32", "X64", "IPF", "ARM"): + raise Warning("Unknown Arch At line ", self.FileName, self.CurrentLineNumber) + VtfObj.ArchList = self.__Token.upper() + + if not self.__IsToken( "]"): + raise Warning("expected ']' At Line ", self.FileName, self.CurrentLineNumber) + + if self.__IsKeyword("IA32_RST_BIN"): + if not self.__IsToken("="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Reset file At Line ", self.FileName, self.CurrentLineNumber) + + VtfObj.ResetBin = self.__Token + + while self.__GetComponentStatement(VtfObj): + pass + + self.Profile.VtfList.append(VtfObj) + return True + + ## __GetComponentStatement() method + # + # Get components in VTF + # + # @param self The object pointer + # @param VtfObj for whom component is got + # @retval True Successfully find a component + # @retval False Not able to find a component + # + def __GetComponentStatement(self, VtfObj): + + if not self.__IsKeyword("COMP_NAME"): + return False + + if not self.__IsToken("="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextWord(): + raise Warning("expected Component Name At Line ", self.FileName, self.CurrentLineNumber) + + CompStatementObj = ComponentStatement.ComponentStatement() + CompStatementObj.CompName = self.__Token + + if not self.__IsKeyword("COMP_LOC"): + raise Warning("expected COMP_LOC At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + CompStatementObj.CompLoc = "" + if self.__GetNextWord(): + CompStatementObj.CompLoc = self.__Token + if self.__IsToken('|'): + if not self.__GetNextWord(): + raise Warning("Expected Region Name At Line ", self.FileName, self.CurrentLineNumber) + + if self.__Token not in ("F", "N", "S"): #, "H", "L", "PH", "PL"): not support + raise Warning("Unknown location type At line ", self.FileName, self.CurrentLineNumber) + + CompStatementObj.FilePos = self.__Token + else: + self.CurrentLineNumber += 1 + self.CurrentOffsetWithinLine = 0 + + if not self.__IsKeyword("COMP_TYPE"): + raise Warning("expected COMP_TYPE At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Component type At Line ", self.FileName, self.CurrentLineNumber) + if self.__Token not in ("FIT", "PAL_B", "PAL_A", "OEM"): + if not self.__Token.startswith("0x") or len(self.__Token) < 3 or len(self.__Token) > 4 or \ + not self.__HexDigit(self.__Token[2]) or not self.__HexDigit(self.__Token[-1]): + raise Warning("Unknown location type At line ", self.FileName, self.CurrentLineNumber) + CompStatementObj.CompType = self.__Token + + if not self.__IsKeyword("COMP_VER"): + raise Warning("expected COMP_VER At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Component version At Line ", self.FileName, self.CurrentLineNumber) + + Pattern = re.compile('-$|[0-9]{0,1}[0-9]{1}\.[0-9]{0,1}[0-9]{1}') + if Pattern.match(self.__Token) == None: + raise Warning("Unknown version format At line ", self.FileName, self.CurrentLineNumber) + CompStatementObj.CompVer = self.__Token + + if not self.__IsKeyword("COMP_CS"): + raise Warning("expected COMP_CS At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Component CS At Line ", self.FileName, self.CurrentLineNumber) + if self.__Token not in ("1", "0"): + raise Warning("Unknown Component CS At line ", self.FileName, self.CurrentLineNumber) + CompStatementObj.CompCs = self.__Token + + + if not self.__IsKeyword("COMP_BIN"): + raise Warning("expected COMP_BIN At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Component file At Line ", self.FileName, self.CurrentLineNumber) + + CompStatementObj.CompBin = self.__Token + + if not self.__IsKeyword("COMP_SYM"): + raise Warning("expected COMP_SYM At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Component symbol file At Line ", self.FileName, self.CurrentLineNumber) + + CompStatementObj.CompSym = self.__Token + + if not self.__IsKeyword("COMP_SIZE"): + raise Warning("expected COMP_SIZE At Line ", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '=' At Line ", self.FileName, self.CurrentLineNumber) + + if self.__IsToken("-"): + CompStatementObj.CompSize = self.__Token + elif self.__GetNextDecimalNumber(): + CompStatementObj.CompSize = self.__Token + elif self.__GetNextHexNumber(): + CompStatementObj.CompSize = self.__Token + else: + raise Warning("Unknown size At line ", self.FileName, self.CurrentLineNumber) + + VtfObj.ComponentStatementList.append(CompStatementObj) + return True + + ## __GetFvInFd() method + # + # Get FV list contained in FD + # + # @param self The object pointer + # @param FdName FD name + # @retval FvList list of FV in FD + # + def __GetFvInFd (self, FdName): + + FvList = [] + if FdName.upper() in self.Profile.FdDict.keys(): + FdObj = self.Profile.FdDict[FdName.upper()] + for elementRegion in FdObj.RegionList: + if elementRegion.RegionType == 'FV': + for elementRegionData in elementRegion.RegionDataList: + if elementRegionData != None and elementRegionData.upper() not in FvList: + FvList.append(elementRegionData.upper()) + return FvList + + ## __GetReferencedFdFvTuple() method + # + # Get FD and FV list referenced by a FFS file + # + # @param self The object pointer + # @param FfsFile contains sections to be searched + # @param RefFdList referenced FD by section + # @param RefFvList referenced FV by section + # + def __GetReferencedFdFvTuple(self, FvObj, RefFdList = [], RefFvList = []): + + for FfsObj in FvObj.FfsList: + if isinstance(FfsObj, FfsFileStatement.FileStatement): + if FfsObj.FvName != None and FfsObj.FvName.upper() not in RefFvList: + RefFvList.append(FfsObj.FvName.upper()) + elif FfsObj.FdName != None and FfsObj.FdName.upper() not in RefFdList: + RefFdList.append(FfsObj.FdName.upper()) + else: + self.__GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList) + + ## __GetReferencedFdFvTupleFromSection() method + # + # Get FD and FV list referenced by a FFS section + # + # @param self The object pointer + # @param FfsFile contains sections to be searched + # @param FdList referenced FD by section + # @param FvList referenced FV by section + # + def __GetReferencedFdFvTupleFromSection(self, FfsFile, FdList = [], FvList = []): + + SectionStack = [] + SectionStack.extend(FfsFile.SectionList) + while SectionStack != []: + SectionObj = SectionStack.pop() + if isinstance(SectionObj, FvImageSection.FvImageSection): + if SectionObj.FvName != None and SectionObj.FvName.upper() not in FvList: + FvList.append(SectionObj.FvName.upper()) + if SectionObj.Fv != None and SectionObj.Fv.UiFvName != None and SectionObj.Fv.UiFvName.upper() not in FvList: + FvList.append(SectionObj.Fv.UiFvName.upper()) + self.__GetReferencedFdFvTuple(SectionObj.Fv, FdList, FvList) + + if isinstance(SectionObj, CompressSection.CompressSection) or isinstance(SectionObj, GuidSection.GuidSection): + SectionStack.extend(SectionObj.SectionList) + + ## CycleReferenceCheck() method + # + # Check whether cycle reference exists in FDF + # + # @param self The object pointer + # @retval True cycle reference exists + # @retval False Not exists cycle reference + # + def CycleReferenceCheck(self): + + CycleRefExists = False + + try: + for FvName in self.Profile.FvDict.keys(): + LogStr = "Cycle Reference Checking for FV: %s\n" % FvName + RefFvStack = [] + RefFvStack.append(FvName) + FdAnalyzedList = [] + + while RefFvStack != []: + FvNameFromStack = RefFvStack.pop() + if FvNameFromStack.upper() in self.Profile.FvDict.keys(): + FvObj = self.Profile.FvDict[FvNameFromStack.upper()] + else: + continue + + RefFdList = [] + RefFvList = [] + self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList) + + for RefFdName in RefFdList: + if RefFdName in FdAnalyzedList: + continue + + LogStr += "FD %s is referenced by FV %s\n" % (RefFdName, FvNameFromStack) + FvInFdList = self.__GetFvInFd(RefFdName) + if FvInFdList != []: + LogStr += "FD %s contains FV: " % RefFdName + for FvObj in FvInFdList: + LogStr += FvObj + LogStr += ' \n' + if FvObj not in RefFvStack: + RefFvStack.append(FvObj) + + if FvName in RefFvStack: + CycleRefExists = True + raise Warning(LogStr) + FdAnalyzedList.append(RefFdName) + + for RefFvName in RefFvList: + LogStr += "FV %s is referenced by FV %s\n" % (RefFvName, FvNameFromStack) + if RefFvName not in RefFvStack: + RefFvStack.append(RefFvName) + + if FvName in RefFvStack: + CycleRefExists = True + raise Warning(LogStr) + + except Warning: + print LogStr + + finally: + return CycleRefExists + +if __name__ == "__main__": + parser = FdfParser("..\LakeportX64Pkg.fdf") + try: + parser.ParseFile() + parser.CycleReferenceCheck() + except Warning, X: + print X.message + else: + print "Success!" + diff --git a/BaseTools/Source/Python/Common/GlobalData.py b/BaseTools/Source/Python/Common/GlobalData.py new file mode 100644 index 0000000000..d56152ec8a --- /dev/null +++ b/BaseTools/Source/Python/Common/GlobalData.py @@ -0,0 +1,37 @@ +## @file +# This file is used to define common static strings used by INF/DEC/DSC files +# +# Copyright (c) 2007, 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 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 re + +gIsWindows = None + +gEdkCompatibilityPkg = "EdkCompatibilityPkg" +gWorkspace = "." +gEdkSource = "EdkCompatibilityPkg" +gEfiSource = "." +gEcpSource = "EdkCompatibilityPkg" + +gOptions = None +gCaseInsensitive = False +gGlobalDefines = {} +gAllFiles = None + +gEdkGlobal = {} +gOverrideDir = {} + +# for debug trace purpose when problem occurs +gProcessingFile = '' +gBuildingModule = '' + +## Regular expression for matching macro used in DSC/DEC/INF file inclusion +gMacroPattern = re.compile("\$\(([_A-Z][_A-Z0-9]*)\)", re.UNICODE) + diff --git a/BaseTools/Source/Python/Common/Identification.py b/BaseTools/Source/Python/Common/Identification.py new file mode 100644 index 0000000000..a9b2f33d55 --- /dev/null +++ b/BaseTools/Source/Python/Common/Identification.py @@ -0,0 +1,58 @@ +## @file +# This file is used to define the identification of INF/DEC/DSC files +# +# Copyright (c) 2007, 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 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. + +## Identification +# +# This class defined basic Identification information structure which is used by INF/DEC/DSC files +# +# @param object: Inherited from object class +# +# @var FileName: To store data for Filename +# @var FileFullPath: To store data for full path of the file +# @var FileRelativePath: To store data for relative path of the file +# @var RunStatus: Status of build system running +# +class Identification(object): + def __init__(self): + self.FileName = '' + self.FileFullPath = '' + self.FileRelativePath = '' + self.PackagePath = '' + + ## GetFileName + # + # Reserved + # + def GetFileName(self, FileFullPath, FileRelativePath): + pass + + ## GetFileName + # + # Reserved + # + def GetFileFullPath(self, FileName, FileRelativePath): + pass + + ## GetFileName + # + # Reserved + # + def GetFileRelativePath(self, FileName, FileFullPath): + pass + +## +# +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +# +if __name__ == '__main__': + id = Identification() diff --git a/BaseTools/Source/Python/Common/InfClassObject.py b/BaseTools/Source/Python/Common/InfClassObject.py new file mode 100644 index 0000000000..a772840227 --- /dev/null +++ b/BaseTools/Source/Python/Common/InfClassObject.py @@ -0,0 +1,1116 @@ +## @file +# This file is used to define each component of INF file +# +# Copyright (c) 2007, 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 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 re +import EdkLogger +from CommonDataClass.CommonClass import LibraryClassClass +from CommonDataClass.ModuleClass import * +from String import * +from DataType import * +from Identification import * +from Dictionary import * +from BuildToolError import * +from Misc import sdict +import GlobalData +from Table.TableInf import TableInf +import Database +from Parsing import * + +# +# Global variable +# +Section = {TAB_UNKNOWN.upper() : MODEL_UNKNOWN, + TAB_INF_DEFINES.upper() : MODEL_META_DATA_HEADER, + TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION, + TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE, + TAB_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE, + TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS, + TAB_PACKAGES.upper() : MODEL_META_DATA_PACKAGE, + TAB_NMAKE.upper() : MODEL_META_DATA_NMAKE, + TAB_INF_FIXED_PCD.upper() : MODEL_PCD_FIXED_AT_BUILD, + TAB_INF_PATCH_PCD.upper() : MODEL_PCD_PATCHABLE_IN_MODULE, + TAB_INF_FEATURE_PCD.upper() : MODEL_PCD_FEATURE_FLAG, + TAB_INF_PCD_EX.upper() : MODEL_PCD_DYNAMIC_EX, + TAB_INF_PCD.upper() : MODEL_PCD_DYNAMIC, + TAB_SOURCES.upper() : MODEL_EFI_SOURCE_FILE, + TAB_GUIDS.upper() : MODEL_EFI_GUID, + TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL, + TAB_PPIS.upper() : MODEL_EFI_PPI, + TAB_DEPEX.upper() : MODEL_EFI_DEPEX, + TAB_BINARIES.upper() : MODEL_EFI_BINARY_FILE, + TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION + } + +gComponentType2ModuleType = { + "LIBRARY" : "BASE", + "SECURITY_CORE" : "SEC", + "PEI_CORE" : "PEI_CORE", + "COMBINED_PEIM_DRIVER" : "PEIM", + "PIC_PEIM" : "PEIM", + "RELOCATABLE_PEIM" : "PEIM", + "PE32_PEIM" : "PEIM", + "BS_DRIVER" : "DXE_DRIVER", + "RT_DRIVER" : "DXE_RUNTIME_DRIVER", + "SAL_RT_DRIVER" : "DXE_SAL_DRIVER", +# "BS_DRIVER" : "DXE_SMM_DRIVER", +# "BS_DRIVER" : "UEFI_DRIVER", + "APPLICATION" : "UEFI_APPLICATION", + "LOGO" : "BASE", +} + +gNmakeFlagPattern = re.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re.UNICODE) +gNmakeFlagName2ToolCode = { + "C" : "CC", + "LIB" : "SLINK", + "LINK" : "DLINK", +} + +class InfHeader(ModuleHeaderClass): + _Mapping_ = { + # + # Required Fields + # + TAB_INF_DEFINES_BASE_NAME : "Name", + TAB_INF_DEFINES_FILE_GUID : "Guid", + TAB_INF_DEFINES_MODULE_TYPE : "ModuleType", + TAB_INF_DEFINES_EFI_SPECIFICATION_VERSION : "EfiSpecificationVersion", + TAB_INF_DEFINES_EDK_RELEASE_VERSION : "EdkReleaseVersion", + # + # Optional Fields + # + TAB_INF_DEFINES_INF_VERSION : "InfVersion", + TAB_INF_DEFINES_BINARY_MODULE : "BinaryModule", + TAB_INF_DEFINES_COMPONENT_TYPE : "ComponentType", + TAB_INF_DEFINES_MAKEFILE_NAME : "MakefileName", + TAB_INF_DEFINES_BUILD_NUMBER : "BuildNumber", + TAB_INF_DEFINES_BUILD_TYPE : "BuildType", + TAB_INF_DEFINES_FFS_EXT : "FfsExt", + TAB_INF_DEFINES_FV_EXT : "FvExt", + TAB_INF_DEFINES_SOURCE_FV : "SourceFv", + TAB_INF_DEFINES_VERSION_NUMBER : "VersionNumber", + TAB_INF_DEFINES_VERSION_STRING : "VersionString", + TAB_INF_DEFINES_VERSION : "Version", + TAB_INF_DEFINES_PCD_IS_DRIVER : "PcdIsDriver", + TAB_INF_DEFINES_TIANO_R8_FLASHMAP_H : "TianoR8FlashMap_h", + TAB_INF_DEFINES_SHADOW : "Shadow", +# TAB_INF_DEFINES_LIBRARY_CLASS : "LibraryClass", +# TAB_INF_DEFINES_ENTRY_POINT : "ExternImages", +# TAB_INF_DEFINES_UNLOAD_IMAGE : "ExternImages", +# TAB_INF_DEFINES_CONSTRUCTOR : , +# TAB_INF_DEFINES_DESTRUCTOR : , +# TAB_INF_DEFINES_DEFINE : "Define", +# TAB_INF_DEFINES_SPEC : "Specification", +# TAB_INF_DEFINES_CUSTOM_MAKEFILE : "CustomMakefile", +# TAB_INF_DEFINES_MACRO : + } + + def __init__(self): + ModuleHeaderClass.__init__(self) + self.VersionNumber = '' + self.VersionString = '' + #print self.__dict__ + def __setitem__(self, key, value): + self.__dict__[self._Mapping_[key]] = value + def __getitem__(self, key): + return self.__dict__[self._Mapping_[key]] + ## "in" test support + def __contains__(self, key): + return key in self._Mapping_ + +## InfObject +# +# This class defined basic Inf object which is used by inheriting +# +# @param object: Inherited from object class +# +class InfObject(object): + def __init__(self): + object.__init__() + +## Inf +# +# This class defined the structure used in Inf object +# +# @param InfObject: Inherited from InfObject class +# @param Ffilename: Input value for Ffilename of Inf file, default is None +# @param IsMergeAllArches: Input value for IsMergeAllArches +# True is to merge all arches +# Fales is not to merge all arches +# default is False +# @param IsToModule: Input value for IsToModule +# True is to transfer to ModuleObject automatically +# False is not to transfer to ModuleObject automatically +# default is False +# @param WorkspaceDir: Input value for current workspace directory, default is None +# +# @var Identification: To store value for Identification, it is a structure as Identification +# @var UserExtensions: To store value for UserExtensions +# @var Module: To store value for Module, it is a structure as ModuleClass +# @var WorkspaceDir: To store value for WorkspaceDir +# @var KeyList: To store value for KeyList, a list for all Keys used in Inf +# +class Inf(InfObject): + def __init__(self, Filename = None, IsToDatabase = False, IsToModule = False, WorkspaceDir = None, Database = None, SupArchList = DataType.ARCH_LIST): + self.Identification = Identification() + self.Module = ModuleClass() + self.UserExtensions = '' + self.WorkspaceDir = WorkspaceDir + self.SupArchList = SupArchList + self.IsToDatabase = IsToDatabase + + self.Cur = Database.Cur + self.TblFile = Database.TblFile + self.TblInf = Database.TblInf + self.FileID = -1 + #self.TblInf = TableInf(Database.Cur) + + self.KeyList = [ + TAB_SOURCES, TAB_BUILD_OPTIONS, TAB_BINARIES, TAB_INCLUDES, TAB_GUIDS, + TAB_PROTOCOLS, TAB_PPIS, TAB_LIBRARY_CLASSES, TAB_PACKAGES, TAB_LIBRARIES, + TAB_INF_FIXED_PCD, TAB_INF_PATCH_PCD, TAB_INF_FEATURE_PCD, TAB_INF_PCD, + TAB_INF_PCD_EX, TAB_DEPEX, TAB_NMAKE, TAB_INF_DEFINES + ] + # + # Upper all KEYs to ignore case sensitive when parsing + # + self.KeyList = map(lambda c: c.upper(), self.KeyList) + + # + # Init RecordSet + # + self.RecordSet = {} + for Key in self.KeyList: + self.RecordSet[Section[Key]] = [] + + # + # Load Inf file if filename is not None + # + if Filename != None: + self.LoadInfFile(Filename) + + # + # Transfer to Module Object if IsToModule is True + # + if IsToModule: + self.InfToModule() + + ## Transfer to Module Object + # + # Transfer all contents of an Inf file to a standard Module Object + # + def InfToModule(self): + # + # Init global information for the file + # + ContainerFile = self.Identification.FileFullPath + + # + # Generate Package Header + # + self.GenModuleHeader(ContainerFile) + + # + # Generate BuildOptions + # + self.GenBuildOptions(ContainerFile) + + # + # Generate Includes + # + self.GenIncludes(ContainerFile) + + # + # Generate Libraries + # + self.GenLibraries(ContainerFile) + + # + # Generate LibraryClasses + # + self.GenLibraryClasses(ContainerFile) + + # + # Generate Packages + # + self.GenPackages(ContainerFile) + + # + # Generate Nmakes + # + self.GenNmakes(ContainerFile) + + # + # Generate Pcds + # + self.GenPcds(ContainerFile) + + # + # Generate Sources + # + self.GenSources(ContainerFile) + + # + # Generate UserExtensions + # + self.GenUserExtensions(ContainerFile) + + # + # Generate Guids + # + self.GenGuidProtocolPpis(DataType.TAB_GUIDS, ContainerFile) + + # + # Generate Protocols + # + self.GenGuidProtocolPpis(DataType.TAB_PROTOCOLS, ContainerFile) + + # + # Generate Ppis + # + self.GenGuidProtocolPpis(DataType.TAB_PPIS, ContainerFile) + + # + # Generate Depexes + # + self.GenDepexes(ContainerFile) + + # + # Generate Binaries + # + self.GenBinaries(ContainerFile) + + ## Parse [Defines] section + # + # Parse [Defines] section into InfDefines object + # + # @param InfFile The path of the INF file + # @param Section The title of "Defines" section + # @param Lines The content of "Defines" section + # + def ParseDefines(self, InfFile, Section, Lines): + TokenList = Section.split(TAB_SPLIT) + if len(TokenList) == 3: + RaiseParserError(Section, "Defines", InfFile, "[xx.yy.%s] format (with platform) is not supported") + if len(TokenList) == 2: + Arch = TokenList[1].upper() + else: + Arch = TAB_ARCH_COMMON + + if Arch not in self.Defines: + self.Defines[Arch] = InfDefines() + GetSingleValueOfKeyFromLines(Lines, self.Defines[Arch].DefinesDictionary, + TAB_COMMENT_SPLIT, TAB_EQUAL_SPLIT, False, None) + + ## Load Inf file + # + # Load the file if it exists + # + # @param Filename: Input value for filename of Inf file + # + def LoadInfFile(self, Filename): + # + # Insert a record for file + # + Filename = NormPath(Filename) + self.Identification.FileFullPath = Filename + (self.Identification.FileRelativePath, self.Identification.FileName) = os.path.split(Filename) + self.FileID = self.TblFile.InsertFile(Filename, MODEL_FILE_INF) + + # + # Init InfTable + # + #self.TblInf.Table = "Inf%s" % self.FileID + #self.TblInf.Create() + + # + # Init common datas + # + IfDefList, SectionItemList, CurrentSection, ArchList, ThirdList, IncludeFiles = \ + [], [], TAB_UNKNOWN, [], [], [] + LineNo = 0 + + # + # Parse file content + # + IsFindBlockComment = False + ReservedLine = '' + for Line in open(Filename, 'r'): + LineNo = LineNo + 1 + # + # Remove comment block + # + if Line.find(TAB_COMMENT_R8_START) > -1: + ReservedLine = GetSplitValueList(Line, TAB_COMMENT_R8_START, 1)[0] + IsFindBlockComment = True + if Line.find(TAB_COMMENT_R8_END) > -1: + Line = ReservedLine + GetSplitValueList(Line, TAB_COMMENT_R8_END, 1)[1] + ReservedLine = '' + IsFindBlockComment = False + if IsFindBlockComment: + continue + + # + # Remove comments at tail and remove spaces again + # + Line = CleanString(Line) + if Line == '': + continue + + # + # Find a new section tab + # First insert previous section items + # And then parse the content of the new section + # + if Line.startswith(TAB_SECTION_START) and Line.endswith(TAB_SECTION_END): + if Line[1:3] == "--": + continue + Model = Section[CurrentSection.upper()] + # + # Insert items data of previous section + # + InsertSectionItemsIntoDatabase(self.TblInf, self.FileID, Filename, Model, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList, self.RecordSet) + # + # Parse the new section + # + SectionItemList = [] + ArchList = [] + ThirdList = [] + + CurrentSection = '' + LineList = GetSplitValueList(Line[len(TAB_SECTION_START):len(Line) - len(TAB_SECTION_END)], TAB_COMMA_SPLIT) + for Item in LineList: + ItemList = GetSplitValueList(Item, TAB_SPLIT) + if CurrentSection == '': + CurrentSection = ItemList[0] + else: + if CurrentSection != ItemList[0]: + EdkLogger.error("Parser", PARSER_ERROR, "Different section names '%s' and '%s' are found in one section definition, this is not allowed." % (CurrentSection, ItemList[0]), File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError) + if CurrentSection.upper() not in self.KeyList: + RaiseParserError(Line, CurrentSection, Filename, '', LineNo) + CurrentSection = TAB_UNKNOWN + continue + ItemList.append('') + ItemList.append('') + if len(ItemList) > 5: + RaiseParserError(Line, CurrentSection, Filename, '', LineNo) + else: + if ItemList[1] != '' and ItemList[1].upper() not in ARCH_LIST_FULL: + EdkLogger.error("Parser", PARSER_ERROR, "Invalid Arch definition '%s' found" % ItemList[1], File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError) + ArchList.append(ItemList[1].upper()) + ThirdList.append(ItemList[2]) + + continue + + # + # Not in any defined section + # + if CurrentSection == TAB_UNKNOWN: + ErrorMsg = "%s is not in any defined section" % Line + EdkLogger.error("Parser", PARSER_ERROR, ErrorMsg, File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError) + + # + # Add a section item + # + SectionItemList.append([Line, LineNo]) + # End of parse + #End of For + + # + # Insert items data of last section + # + Model = Section[CurrentSection.upper()] + InsertSectionItemsIntoDatabase(self.TblInf, self.FileID, Filename, Model, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList, self.RecordSet) + + # + # Replace all DEFINE macros with its actual values + # + ParseDefineMacro2(self.TblInf, self.RecordSet, GlobalData.gGlobalDefines) + + ## Show detailed information of Module + # + # Print all members and their values of Module class + # + def ShowModule(self): + M = self.Module + for Arch in M.Header.keys(): + print '\nArch =', Arch + print 'Filename =', M.Header[Arch].FileName + print 'FullPath =', M.Header[Arch].FullPath + print 'BaseName =', M.Header[Arch].Name + print 'Guid =', M.Header[Arch].Guid + print 'Version =', M.Header[Arch].Version + print 'InfVersion =', M.Header[Arch].InfVersion + print 'EfiSpecificationVersion =', M.Header[Arch].EfiSpecificationVersion + print 'EdkReleaseVersion =', M.Header[Arch].EdkReleaseVersion + print 'ModuleType =', M.Header[Arch].ModuleType + print 'BinaryModule =', M.Header[Arch].BinaryModule + print 'ComponentType =', M.Header[Arch].ComponentType + print 'MakefileName =', M.Header[Arch].MakefileName + print 'BuildNumber =', M.Header[Arch].BuildNumber + print 'BuildType =', M.Header[Arch].BuildType + print 'FfsExt =', M.Header[Arch].FfsExt + print 'FvExt =', M.Header[Arch].FvExt + print 'SourceFv =', M.Header[Arch].SourceFv + print 'PcdIsDriver =', M.Header[Arch].PcdIsDriver + print 'TianoR8FlashMap_h =', M.Header[Arch].TianoR8FlashMap_h + print 'Shadow =', M.Header[Arch].Shadow + print 'LibraryClass =', M.Header[Arch].LibraryClass + for Item in M.Header[Arch].LibraryClass: + print Item.LibraryClass, DataType.TAB_VALUE_SPLIT.join(Item.SupModuleList) + print 'CustomMakefile =', M.Header[Arch].CustomMakefile + print 'Define =', M.Header[Arch].Define + print 'Specification =', M.Header[Arch].Specification + for Item in self.Module.ExternImages: + print '\nEntry_Point = %s, UnloadImage = %s' % (Item.ModuleEntryPoint, Item.ModuleUnloadImage) + for Item in self.Module.ExternLibraries: + print 'Constructor = %s, Destructor = %s' % (Item.Constructor, Item.Destructor) + print '\nBuildOptions =', M.BuildOptions + for Item in M.BuildOptions: + print Item.ToolChainFamily, Item.ToolChain, Item.Option, Item.SupArchList + print '\nIncludes =', M.Includes + for Item in M.Includes: + print Item.FilePath, Item.SupArchList + print '\nLibraries =', M.Libraries + for Item in M.Libraries: + print Item.Library, Item.SupArchList + print '\nLibraryClasses =', M.LibraryClasses + for Item in M.LibraryClasses: + print Item.LibraryClass, Item.RecommendedInstance, Item.FeatureFlag, Item.SupModuleList, Item.SupArchList, Item.Define + print '\nPackageDependencies =', M.PackageDependencies + for Item in M.PackageDependencies: + print Item.FilePath, Item.SupArchList, Item.FeatureFlag + print '\nNmake =', M.Nmake + for Item in M.Nmake: + print Item.Name, Item.Value, Item.SupArchList + print '\nPcds =', M.PcdCodes + for Item in M.PcdCodes: + print '\tCName=',Item.CName, 'TokenSpaceGuidCName=', Item.TokenSpaceGuidCName, 'DefaultValue=', Item.DefaultValue, 'ItemType=', Item.ItemType, Item.SupArchList + print '\nSources =', M.Sources + for Source in M.Sources: + print Source.SourceFile, 'Fam=', Source.ToolChainFamily, 'Pcd=', Source.FeatureFlag, 'Tag=', Source.TagName, 'ToolCode=', Source.ToolCode, Source.SupArchList + print '\nUserExtensions =', M.UserExtensions + for UserExtension in M.UserExtensions: + print UserExtension.UserID, UserExtension.Identifier,UserExtension.Content + print '\nGuids =', M.Guids + for Item in M.Guids: + print Item.CName, Item.SupArchList, Item.FeatureFlag + print '\nProtocols =', M.Protocols + for Item in M.Protocols: + print Item.CName, Item.SupArchList, Item.FeatureFlag + print '\nPpis =', M.Ppis + for Item in M.Ppis: + print Item.CName, Item.SupArchList, Item.FeatureFlag + print '\nDepex =', M.Depex + for Item in M.Depex: + print Item.Depex, Item.SupArchList, Item.Define + print '\nBinaries =', M.Binaries + for Binary in M.Binaries: + print 'Type=', Binary.FileType, 'Target=', Binary.Target, 'Name=', Binary.BinaryFile, 'FeatureFlag=', Binary.FeatureFlag, 'SupArchList=', Binary.SupArchList + + ## Convert [Defines] section content to ModuleHeaderClass + # + # Convert [Defines] section content to ModuleHeaderClass + # + # @param Defines The content under [Defines] section + # @param ModuleHeader An object of ModuleHeaderClass + # @param Arch The supported ARCH + # + def GenModuleHeader(self, ContainerFile): + EdkLogger.debug(2, "Generate ModuleHeader ...") + File = self.Identification.FileFullPath + # + # Update all defines item in database + # + RecordSet = self.RecordSet[MODEL_META_DATA_HEADER] + for Record in RecordSet: + ValueList = GetSplitValueList(Record[0], TAB_EQUAL_SPLIT) + if len(ValueList) != 2: + RaiseParserError(Record[0], 'Defines', ContainerFile, ' = ', Record[2]) + ID, Value1, Value2, Arch, LineNo = Record[3], ValueList[0], ValueList[1], Record[1], Record[2] + SqlCommand = """update %s set Value1 = '%s', Value2 = '%s' + where ID = %s""" % (self.TblInf.Table, ConvertToSqlString2(Value1), ConvertToSqlString2(Value2), ID) + self.TblInf.Exec(SqlCommand) + + for Arch in DataType.ARCH_LIST: + ModuleHeader = InfHeader() + ModuleHeader.FileName = self.Identification.FileName + ModuleHeader.FullPath = self.Identification.FileFullPath + DefineList = QueryDefinesItem2(self.TblInf, Arch, self.FileID) + + NotProcessedDefineList = [] + for D in DefineList: + if D[0] in ModuleHeader: + ModuleHeader[D[0]] = GetSplitValueList(D[1])[0] + else: + NotProcessedDefineList.append(D) + + if ModuleHeader.ComponentType == "LIBRARY": + Lib = LibraryClassClass() + Lib.LibraryClass = ModuleHeader.Name + Lib.SupModuleList = DataType.SUP_MODULE_LIST + ModuleHeader.LibraryClass.append(Lib) + + # we need to make some key defines resolved first + for D in NotProcessedDefineList: + if D[0] == TAB_INF_DEFINES_LIBRARY_CLASS: + List = GetSplitValueList(D[1], DataType.TAB_VALUE_SPLIT, 1) + Lib = LibraryClassClass() + Lib.LibraryClass = CleanString(List[0]) + if len(List) == 1: + Lib.SupModuleList = DataType.SUP_MODULE_LIST + elif len(List) == 2: + Lib.SupModuleList = GetSplitValueList(CleanString(List[1]), ' ') + ModuleHeader.LibraryClass.append(Lib) + elif D[0] == TAB_INF_DEFINES_CUSTOM_MAKEFILE: + List = D[1].split(DataType.TAB_VALUE_SPLIT) + if len(List) == 2: + ModuleHeader.CustomMakefile[CleanString(List[0])] = CleanString(List[1]) + else: + RaiseParserError(D[1], 'CUSTOM_MAKEFILE of Defines', File, 'CUSTOM_MAKEFILE=|', D[2]) + elif D[0] == TAB_INF_DEFINES_ENTRY_POINT: + Image = ModuleExternImageClass() + Image.ModuleEntryPoint = CleanString(D[1]) + self.Module.ExternImages.append(Image) + elif D[0] == TAB_INF_DEFINES_UNLOAD_IMAGE: + Image = ModuleExternImageClass() + Image.ModuleUnloadImage = CleanString(D[1]) + self.Module.ExternImages.append(Image) + elif D[0] == TAB_INF_DEFINES_CONSTRUCTOR: + LibraryClass = ModuleExternLibraryClass() + LibraryClass.Constructor = CleanString(D[1]) + self.Module.ExternLibraries.append(LibraryClass) + elif D[0] == TAB_INF_DEFINES_DESTRUCTOR: + LibraryClass = ModuleExternLibraryClass() + LibraryClass.Destructor = CleanString(D[1]) + self.Module.ExternLibraries.append(LibraryClass) + elif D[0] == TAB_INF_DEFINES_DEFINE: + List = D[1].split(DataType.TAB_EQUAL_SPLIT) + if len(List) != 2: + RaiseParserError(Item, 'DEFINE of Defines', File, 'DEFINE = ', D[2]) + else: + ModuleHeader.Define[CleanString(List[0])] = CleanString(List[1]) + elif D[0] == TAB_INF_DEFINES_SPEC: + List = D[1].split(DataType.TAB_EQUAL_SPLIT) + if len(List) != 2: + RaiseParserError(Item, 'SPEC of Defines', File, 'SPEC = ', D[2]) + else: + ModuleHeader.Specification[CleanString(List[0])] = CleanString(List[1]) + + # + # Get version of INF + # + if ModuleHeader.InfVersion != "": + # R9 inf + VersionNumber = ModuleHeader.VersionNumber + VersionString = ModuleHeader.VersionString + if len(VersionNumber) > 0 and len(VersionString) == 0: + EdkLogger.warn(2000, 'VERSION_NUMBER depricated; INF file %s should be modified to use VERSION_STRING instead.' % self.Identification.FileFullPath) + ModuleHeader.Version = VersionNumber + if len(VersionString) > 0: + if len(VersionNumber) > 0: + EdkLogger.warn(2001, 'INF file %s defines both VERSION_NUMBER and VERSION_STRING, using VERSION_STRING' % self.Identification.FileFullPath) + ModuleHeader.Version = VersionString + else: + # R8 inf + ModuleHeader.InfVersion = "0x00010000" + if ModuleHeader.ComponentType in gComponentType2ModuleType: + ModuleHeader.ModuleType = gComponentType2ModuleType[ModuleHeader.ComponentType] + elif ModuleHeader.ComponentType != '': + EdkLogger.error("Parser", PARSER_ERROR, "Unsupported R8 component type [%s]" % ModuleHeader.ComponentType, ExtraData=File, RaiseError = EdkLogger.IsRaiseError) + + self.Module.Header[Arch] = ModuleHeader + + + ## GenBuildOptions + # + # Gen BuildOptions of Inf + # [:]=Flag + # + # @param ContainerFile: The Inf file full path + # + def GenBuildOptions(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_BUILD_OPTIONS) + BuildOptions = {} + # + # Get all BuildOptions + # + RecordSet = self.RecordSet[MODEL_META_DATA_BUILD_OPTION] + + # + # Go through each arch + # + for Arch in self.SupArchList: + for Record in RecordSet: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: + (Family, ToolChain, Flag) = GetBuildOption(Record[0], ContainerFile, Record[2]) + MergeArches(BuildOptions, (Family, ToolChain, Flag), Arch) + # + # Update to Database + # + if self.IsToDatabase: + SqlCommand = """update %s set Value1 = '%s', Value2 = '%s', Value3 = '%s' + where ID = %s""" % (self.TblInf.Table, ConvertToSqlString2(Family), ConvertToSqlString2(ToolChain), ConvertToSqlString2(Flag), Record[3]) + self.TblInf.Exec(SqlCommand) + + for Key in BuildOptions.keys(): + BuildOption = BuildOptionClass(Key[0], Key[1], Key[2]) + BuildOption.SupArchList = BuildOptions[Key] + self.Module.BuildOptions.append(BuildOption) + + ## GenIncludes + # + # Gen Includes of Inf + # + # + # @param ContainerFile: The Inf file full path + # + def GenIncludes(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_INCLUDES) + Includes = sdict() + # + # Get all Includes + # + RecordSet = self.RecordSet[MODEL_EFI_INCLUDE] + + # + # Go through each arch + # + for Arch in self.SupArchList: + for Record in RecordSet: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: + MergeArches(Includes, Record[0], Arch) + + for Key in Includes.keys(): + Include = IncludeClass() + Include.FilePath = NormPath(Key) + Include.SupArchList = Includes[Key] + self.Module.Includes.append(Include) + + ## GenLibraries + # + # Gen Libraries of Inf + # + # + # @param ContainerFile: The Inf file full path + # + def GenLibraries(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_LIBRARIES) + Libraries = sdict() + # + # Get all Includes + # + RecordSet = self.RecordSet[MODEL_EFI_LIBRARY_INSTANCE] + + # + # Go through each arch + # + for Arch in self.SupArchList: + for Record in RecordSet: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: + MergeArches(Libraries, Record[0], Arch) + + for Key in Libraries.keys(): + Library = ModuleLibraryClass() + # replace macro and remove file extension + Library.Library = Key.rsplit('.', 1)[0] + Library.SupArchList = Libraries[Key] + self.Module.Libraries.append(Library) + + ## GenLibraryClasses + # + # Get LibraryClass of Inf + # | + # + # @param ContainerFile: The Inf file full path + # + def GenLibraryClasses(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_LIBRARY_CLASSES) + LibraryClasses = {} + # + # Get all LibraryClasses + # + RecordSet = self.RecordSet[MODEL_EFI_LIBRARY_CLASS] + + # + # Go through each arch + # + for Arch in self.SupArchList: + for Record in RecordSet: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: + (LibClassName, LibClassIns, Pcd, SupModelList) = GetLibraryClassOfInf([Record[0], Record[4]], ContainerFile, self.WorkspaceDir, Record[2]) + MergeArches(LibraryClasses, (LibClassName, LibClassIns, Pcd, SupModelList), Arch) + # + # Update to Database + # + if self.IsToDatabase: + SqlCommand = """update %s set Value1 = '%s', Value2 = '%s', Value3 = '%s' + where ID = %s""" % (self.TblInf.Table, ConvertToSqlString2(LibClassName), ConvertToSqlString2(LibClassIns), ConvertToSqlString2(SupModelList), Record[3]) + self.TblInf.Exec(SqlCommand) + + for Key in LibraryClasses.keys(): + KeyList = Key[0].split(DataType.TAB_VALUE_SPLIT) + LibraryClass = LibraryClassClass() + LibraryClass.LibraryClass = Key[0] + LibraryClass.RecommendedInstance = NormPath(Key[1]) + LibraryClass.FeatureFlag = Key[2] + LibraryClass.SupArchList = LibraryClasses[Key] + LibraryClass.SupModuleList = GetSplitValueList(Key[3]) + self.Module.LibraryClasses.append(LibraryClass) + + ## GenPackages + # + # Gen Packages of Inf + # + # + # @param ContainerFile: The Inf file full path + # + def GenPackages(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_PACKAGES) + Packages = {} + # + # Get all Packages + # + RecordSet = self.RecordSet[MODEL_META_DATA_PACKAGE] + + # + # Go through each arch + # + for Arch in self.SupArchList: + for Record in RecordSet: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: + (Package, Pcd) = GetPackage(Record[0], ContainerFile, self.WorkspaceDir, Record[2]) + MergeArches(Packages, (Package, Pcd), Arch) + if self.IsToDatabase: + SqlCommand = """update %s set Value1 = '%s', Value2 = '%s' + where ID = %s""" % (self.TblInf.Table, ConvertToSqlString2(Package), ConvertToSqlString2(Pcd), Record[3]) + self.TblInf.Exec(SqlCommand) + + + for Key in Packages.keys(): + Package = ModulePackageDependencyClass() + Package.FilePath = NormPath(Key[0]) + Package.SupArchList = Packages[Key] + Package.FeatureFlag = Key[1] + self.Module.PackageDependencies.append(Package) + + ## GenNmakes + # + # Gen Nmakes of Inf + # + # + # @param ContainerFile: The Inf file full path + # + def GenNmakes(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_NMAKE) + Nmakes = sdict() + # + # Get all Nmakes + # + RecordSet = self.RecordSet[MODEL_META_DATA_NMAKE] + + + # + # Go through each arch + # + for Arch in self.SupArchList: + for Record in RecordSet: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: + MergeArches(Nmakes, Record[0], Arch) + + for Key in Nmakes.keys(): + List = GetSplitValueList(Key, DataType.TAB_EQUAL_SPLIT, MaxSplit=1) + if len(List) != 2: + RaiseParserError(Key, 'Nmake', ContainerFile, ' = ') + continue + Nmake = ModuleNmakeClass() + Nmake.Name = List[0] + Nmake.Value = List[1] + Nmake.SupArchList = Nmakes[Key] + self.Module.Nmake.append(Nmake) + + # convert R8 format to R9 format + if Nmake.Name == "IMAGE_ENTRY_POINT": + Image = ModuleExternImageClass() + Image.ModuleEntryPoint = Nmake.Value + self.Module.ExternImages.append(Image) + elif Nmake.Name == "DPX_SOURCE": + Source = ModuleSourceFileClass(NormPath(Nmake.Value), "", "", "", "", Nmake.SupArchList) + self.Module.Sources.append(Source) + else: + ToolList = gNmakeFlagPattern.findall(Nmake.Name) + if len(ToolList) == 0 or len(ToolList) != 1: + EdkLogger.warn("\nParser", "Don't know how to do with MACRO: %s" % Nmake.Name, + ExtraData=ContainerFile) + else: + if ToolList[0] in gNmakeFlagName2ToolCode: + Tool = gNmakeFlagName2ToolCode[ToolList[0]] + else: + Tool = ToolList[0] + BuildOption = BuildOptionClass("MSFT", "*_*_*_%s_FLAGS" % Tool, Nmake.Value) + BuildOption.SupArchList = Nmake.SupArchList + self.Module.BuildOptions.append(BuildOption) + + ## GenPcds + # + # Gen Pcds of Inf + # .[|] + # + # @param ContainerFile: The Dec file full path + # + def GenPcds(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_PCDS) + Pcds = {} + PcdToken = {} + + # + # Get all Guids + # + RecordSet1 = self.RecordSet[MODEL_PCD_FIXED_AT_BUILD] + RecordSet2 = self.RecordSet[MODEL_PCD_PATCHABLE_IN_MODULE] + RecordSet3 = self.RecordSet[MODEL_PCD_FEATURE_FLAG] + RecordSet4 = self.RecordSet[MODEL_PCD_DYNAMIC_EX] + RecordSet5 = self.RecordSet[MODEL_PCD_DYNAMIC] + + # + # Go through each arch + # + for Arch in self.SupArchList: + for Record in RecordSet1: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: + if self.Module.Header[Arch].LibraryClass != {}: + pass + (TokenGuidCName, TokenName, Value, Type) = GetPcdOfInf(Record[0], TAB_PCDS_FIXED_AT_BUILD, ContainerFile, Record[2]) + MergeArches(Pcds, (TokenGuidCName, TokenName, Value, Type), Arch) + PcdToken[Record[3]] = (TokenGuidCName, TokenName) + for Record in RecordSet2: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: + (TokenGuidCName, TokenName, Value, Type) = GetPcdOfInf(Record[0], TAB_PCDS_PATCHABLE_IN_MODULE, ContainerFile, Record[2]) + MergeArches(Pcds, (TokenGuidCName, TokenName, Value, Type), Arch) + PcdToken[Record[3]] = (TokenGuidCName, TokenName) + for Record in RecordSet3: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: + (TokenGuidCName, TokenName, Value, Type) = GetPcdOfInf(Record[0], TAB_PCDS_FEATURE_FLAG, ContainerFile, Record[2]) + MergeArches(Pcds, (TokenGuidCName, TokenName, Value, Type), Arch) + PcdToken[Record[3]] = (TokenGuidCName, TokenName) + for Record in RecordSet4: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: + (TokenGuidCName, TokenName, Value, Type) = GetPcdOfInf(Record[0], TAB_PCDS_DYNAMIC_EX, ContainerFile, Record[2]) + MergeArches(Pcds, (TokenGuidCName, TokenName, Value, Type), Arch) + PcdToken[Record[3]] = (TokenGuidCName, TokenName) + for Record in RecordSet5: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: + (TokenGuidCName, TokenName, Value, Type) = GetPcdOfInf(Record[0], "", ContainerFile, Record[2]) + MergeArches(Pcds, (TokenGuidCName, TokenName, Value, Type), Arch) + PcdToken[Record[3]] = (TokenGuidCName, TokenName) + # + # Update to database + # + if self.IsToDatabase: + for Key in PcdToken.keys(): + SqlCommand = """update %s set Value2 = '%s' where ID = %s""" % (self.TblInf.Table, ".".join((PcdToken[Key][0], PcdToken[Key][1])), Key) + self.TblInf.Exec(SqlCommand) + + for Key in Pcds.keys(): + Pcd = PcdClass() + Pcd.CName = Key[1] + Pcd.TokenSpaceGuidCName = Key[0] + Pcd.DefaultValue = Key[2] + Pcd.ItemType = Key[3] + Pcd.SupArchList = Pcds[Key] + self.Module.PcdCodes.append(Pcd) + + ## GenSources + # + # Gen Sources of Inf + # [|[|[|[|]]]] + # + # @param ContainerFile: The Dec file full path + # + def GenSources(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_SOURCES) + Sources = {} + + # + # Get all Nmakes + # + RecordSet = self.RecordSet[MODEL_EFI_SOURCE_FILE] + + # + # Go through each arch + # + for Arch in self.SupArchList: + for Record in RecordSet: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: + (Filename, Family, TagName, ToolCode, Pcd) = GetSource(Record[0], ContainerFile, self.Identification.FileRelativePath, Record[2]) + MergeArches(Sources, (Filename, Family, TagName, ToolCode, Pcd), Arch) + if self.IsToDatabase: + SqlCommand = """update %s set Value1 = '%s', Value2 = '%s', Value3 = '%s', Value4 = '%s', Value5 = '%s' + where ID = %s""" % (self.TblInf.Table, ConvertToSqlString2(Filename), ConvertToSqlString2(Family), ConvertToSqlString2(TagName), ConvertToSqlString2(ToolCode), ConvertToSqlString2(Pcd), Record[3]) + self.TblInf.Exec(SqlCommand) + + for Key in Sources.keys(): + Source = ModuleSourceFileClass(Key[0], Key[2], Key[3], Key[1], Key[4], Sources[Key]) + self.Module.Sources.append(Source) + + ## GenUserExtensions + # + # Gen UserExtensions of Inf + # + def GenUserExtensions(self, ContainerFile): +# # +# # UserExtensions +# # +# if self.UserExtensions != '': +# UserExtension = UserExtensionsClass() +# Lines = self.UserExtensions.splitlines() +# List = GetSplitValueList(Lines[0], DataType.TAB_SPLIT, 2) +# if len(List) != 3: +# RaiseParserError(Lines[0], 'UserExtensions', File, "UserExtensions.UserId.'Identifier'") +# else: +# UserExtension.UserID = List[1] +# UserExtension.Identifier = List[2][0:-1].replace("'", '').replace('\"', '') +# for Line in Lines[1:]: +# UserExtension.Content = UserExtension.Content + CleanString(Line) + '\n' +# self.Module.UserExtensions.append(UserExtension) + pass + + ## GenDepexes + # + # Gen Depex of Inf + # + # @param ContainerFile: The Inf file full path + # + def GenDepexes(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_DEPEX) + Depex = {} + # + # Get all Depexes + # + RecordSet = self.RecordSet[MODEL_EFI_DEPEX] + + # + # Go through each arch + # + for Arch in self.SupArchList: + Line = '' + for Record in RecordSet: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: + Line = Line + Record[0] + ' ' + if Line != '': + MergeArches(Depex, Line, Arch) + + for Key in Depex.keys(): + Dep = ModuleDepexClass() + Dep.Depex = Key + Dep.SupArchList = Depex[Key] + self.Module.Depex.append(Dep) + + ## GenBinaries + # + # Gen Binary of Inf + # ||[|.] + # + # @param ContainerFile: The Dec file full path + # + def GenBinaries(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_BINARIES) + Binaries = {} + + # + # Get all Guids + # + RecordSet = self.RecordSet[MODEL_EFI_BINARY_FILE] + + # + # Go through each arch + # + for Arch in self.SupArchList: + for Record in RecordSet: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: + (FileType, Filename, Target, Pcd) = GetBinary(Record[0], ContainerFile, self.Identification.FileRelativePath, Record[2]) + MergeArches(Binaries, (FileType, Filename, Target, Pcd), Arch) + if self.IsToDatabase: + SqlCommand = """update %s set Value1 = '%s', Value2 = '%s', Value3 = '%s', Value4 = '%s' + where ID = %s""" % (self.TblInf.Table, ConvertToSqlString2(FileType), ConvertToSqlString2(Filename), ConvertToSqlString2(Target), ConvertToSqlString2(Pcd), Record[3]) + self.TblInf.Exec(SqlCommand) + + for Key in Binaries.keys(): + Binary = ModuleBinaryFileClass(NormPath(Key[1]), Key[0], Key[2], Key[3], Binaries[Key]) + self.Module.Binaries.append(Binary) + + ## GenGuids + # + # Gen Guids of Inf + # = + # + # @param ContainerFile: The Inf file full path + # + def GenGuidProtocolPpis(self, Type, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % Type) + Lists = {} + # + # Get all Items + # + RecordSet = self.RecordSet[Section[Type.upper()]] + + # + # Go through each arch + # + for Arch in self.SupArchList: + for Record in RecordSet: + if Record[1] == Arch or Record[1] == TAB_ARCH_COMMON: + (Name, Value) = GetGuidsProtocolsPpisOfInf(Record[0], Type, ContainerFile, Record[2]) + MergeArches(Lists, (Name, Value), Arch) + if self.IsToDatabase: + SqlCommand = """update %s set Value1 = '%s', Value2 = '%s' + where ID = %s""" % (self.TblInf.Table, ConvertToSqlString2(Name), ConvertToSqlString2(Value), Record[3]) + self.TblInf.Exec(SqlCommand) + + ListMember = None + if Type == TAB_GUIDS: + ListMember = self.Module.Guids + elif Type == TAB_PROTOCOLS: + ListMember = self.Module.Protocols + elif Type == TAB_PPIS: + ListMember = self.Module.Ppis + + for Key in Lists.keys(): + ListClass = GuidProtocolPpiCommonClass() + ListClass.CName = Key[0] + ListClass.SupArchList = Lists[Key] + ListClass.FeatureFlag = Key[1] + ListMember.append(ListClass) + +## +# +# 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) + + W = os.getenv('WORKSPACE') + F = os.path.join(W, 'MdeModulePkg/Application/HelloWorld/HelloWorld.inf') + + Db = Database.Database('Inf.db') + Db.InitDatabase() + + P = Inf(os.path.normpath(F), True, True, W, Db) + P.ShowModule() + + Db.Close() diff --git a/BaseTools/Source/Python/Common/InfClassObjectLight.py b/BaseTools/Source/Python/Common/InfClassObjectLight.py new file mode 100644 index 0000000000..a655828e6a --- /dev/null +++ b/BaseTools/Source/Python/Common/InfClassObjectLight.py @@ -0,0 +1,876 @@ +## @file +# This file is used to define each component of INF file +# +# Copyright (c) 2007, 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 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 re +import EdkLogger + +from CommonDataClass.ModuleClass import * +from CommonDataClass import CommonClass +from String import * +from DataType import * +from BuildToolError import * +from Misc import sdict +from Misc import GetFiles +from Parsing import * + +# Global variable +Section = {TAB_UNKNOWN.upper() : MODEL_UNKNOWN, + TAB_INF_DEFINES.upper() : MODEL_META_DATA_HEADER, + TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION, + TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE, + TAB_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE, + TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS, + TAB_PACKAGES.upper() : MODEL_META_DATA_PACKAGE, + TAB_NMAKE.upper() : MODEL_META_DATA_NMAKE, + TAB_INF_FIXED_PCD.upper() : MODEL_PCD_FIXED_AT_BUILD, + TAB_INF_PATCH_PCD.upper() : MODEL_PCD_PATCHABLE_IN_MODULE, + TAB_INF_FEATURE_PCD.upper() : MODEL_PCD_FEATURE_FLAG, + TAB_INF_PCD_EX.upper() : MODEL_PCD_DYNAMIC_EX, + TAB_INF_PCD.upper() : MODEL_PCD_DYNAMIC, + TAB_SOURCES.upper() : MODEL_EFI_SOURCE_FILE, + TAB_GUIDS.upper() : MODEL_EFI_GUID, + TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL, + TAB_PPIS.upper() : MODEL_EFI_PPI, + TAB_DEPEX.upper() : MODEL_EFI_DEPEX, + TAB_BINARIES.upper() : MODEL_EFI_BINARY_FILE, + TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION + } + +gComponentType2ModuleType = { + "LIBRARY" : "BASE", + "SECURITY_CORE" : "SEC", + "PEI_CORE" : "PEI_CORE", + "COMBINED_PEIM_DRIVER" : "PEIM", + "PIC_PEIM" : "PEIM", + "RELOCATABLE_PEIM" : "PEIM", + "PE32_PEIM" : "PEIM", + "BS_DRIVER" : "DXE_DRIVER", + "RT_DRIVER" : "DXE_RUNTIME_DRIVER", + "SAL_RT_DRIVER" : "DXE_SAL_DRIVER", + "APPLICATION" : "UEFI_APPLICATION", + "LOGO" : "BASE", +} + +class InfHeader(ModuleHeaderClass): + _Mapping_ = { + # Required Fields + TAB_INF_DEFINES_BASE_NAME : "Name", + TAB_INF_DEFINES_FILE_GUID : "Guid", + TAB_INF_DEFINES_MODULE_TYPE : "ModuleType", + TAB_INF_DEFINES_EFI_SPECIFICATION_VERSION : "EfiSpecificationVersion", + TAB_INF_DEFINES_EDK_RELEASE_VERSION : "EdkReleaseVersion", + + # Optional Fields + TAB_INF_DEFINES_INF_VERSION : "InfVersion", + TAB_INF_DEFINES_BINARY_MODULE : "BinaryModule", + TAB_INF_DEFINES_COMPONENT_TYPE : "ComponentType", + TAB_INF_DEFINES_MAKEFILE_NAME : "MakefileName", + TAB_INF_DEFINES_BUILD_NUMBER : "BuildNumber", + TAB_INF_DEFINES_BUILD_TYPE : "BuildType", + TAB_INF_DEFINES_FFS_EXT : "FfsExt", + TAB_INF_DEFINES_FV_EXT : "FvExt", + TAB_INF_DEFINES_SOURCE_FV : "SourceFv", + TAB_INF_DEFINES_VERSION_NUMBER : "VersionNumber", + TAB_INF_DEFINES_VERSION_STRING : "VersionString", + TAB_INF_DEFINES_VERSION : "Version", + TAB_INF_DEFINES_PCD_IS_DRIVER : "PcdIsDriver", + TAB_INF_DEFINES_TIANO_R8_FLASHMAP_H : "TianoR8FlashMap_h", + TAB_INF_DEFINES_SHADOW : "Shadow", + } + + def __init__(self): + ModuleHeaderClass.__init__(self) + self.VersionNumber = '' + self.VersionString = '' + #print self.__dict__ + def __setitem__(self, key, value): + self.__dict__[self._Mapping_[key]] = value + def __getitem__(self, key): + return self.__dict__[self._Mapping_[key]] + ## "in" test support + def __contains__(self, key): + return key in self._Mapping_ + +## InfObject +# +# This class defined basic Inf object which is used by inheriting +# +# @param object: Inherited from object class +# +class InfObject(object): + def __init__(self): + object.__init__() + +## Inf +# +# This class defined the structure used in Inf object +# +# @param InfObject: Inherited from InfObject class +# @param Ffilename: Input value for Ffilename of Inf file, default is None +# @param IsMergeAllArches: Input value for IsMergeAllArches +# True is to merge all arches +# Fales is not to merge all arches +# default is False +# @param IsToModule: Input value for IsToModule +# True is to transfer to ModuleObject automatically +# False is not to transfer to ModuleObject automatically +# default is False +# @param WorkspaceDir: Input value for current workspace directory, default is None +# +# @var Identification: To store value for Identification, it is a structure as Identification +# @var UserExtensions: To store value for UserExtensions +# @var Module: To store value for Module, it is a structure as ModuleClass +# @var WorkspaceDir: To store value for WorkspaceDir +# @var KeyList: To store value for KeyList, a list for all Keys used in Inf +# +class Inf(InfObject): + def __init__(self, Filename = None, IsToModule = False, WorkspaceDir = None, PackageDir = None, SupArchList = DataType.ARCH_LIST): + self.Identification = IdentificationClass() + self.Module = ModuleClass() + self.WorkspaceDir = WorkspaceDir + self.PackageDir = PackageDir + self.SupArchList = SupArchList + + self.KeyList = [ + TAB_SOURCES, TAB_BUILD_OPTIONS, TAB_BINARIES, TAB_INCLUDES, TAB_GUIDS, + TAB_PROTOCOLS, TAB_PPIS, TAB_LIBRARY_CLASSES, TAB_PACKAGES, TAB_INF_FIXED_PCD, + TAB_INF_PATCH_PCD, TAB_INF_FEATURE_PCD, TAB_INF_PCD, TAB_INF_PCD_EX, + TAB_DEPEX, TAB_INF_DEFINES + ] + # Upper all KEYs to ignore case sensitive when parsing + self.KeyList = map(lambda c: c.upper(), self.KeyList) + + # Init RecordSet + self.RecordSet = {} + for Key in self.KeyList: + self.RecordSet[Section[Key]] = [] + + # Init Comment + self.SectionHeaderCommentDict = {} + + # Load Inf file if filename is not None + if Filename != None: + self.LoadInfFile(Filename) + + # Transfer to Module Object if IsToModule is True + if IsToModule: + self.InfToModule() + + ## Module Object to INF file + def ModuleToInf(self, Module): + Inf = '' + InfList = sdict() + SectionHeaderCommentDict = {} + if Module == None: + return Inf + + ModuleHeader = Module.ModuleHeader + TmpList = [] + # Common define items + if ModuleHeader.Name: + TmpList.append(TAB_INF_DEFINES_BASE_NAME + ' = ' + ModuleHeader.Name) + if ModuleHeader.Guid: + TmpList.append(TAB_INF_DEFINES_FILE_GUID + ' = ' + ModuleHeader.Guid) + if ModuleHeader.Version: + TmpList.append(TAB_INF_DEFINES_VERSION_STRING + ' = ' + ModuleHeader.Version) + if ModuleHeader.ModuleType: + TmpList.append(TAB_INF_DEFINES_MODULE_TYPE + ' = ' + ModuleHeader.ModuleType) + if ModuleHeader.PcdIsDriver: + TmpList.append(TAB_INF_DEFINES_PCD_IS_DRIVER + ' = ' + ModuleHeader.PcdIsDriver) + # Externs + for Item in Module.Externs: + if Item.EntryPoint: + TmpList.append(TAB_INF_DEFINES_ENTRY_POINT + ' = ' + Item.EntryPoint) + if Item.UnloadImage: + TmpList.append(TAB_INF_DEFINES_UNLOAD_IMAGE + ' = ' + Item.UnloadImage) + if Item.Constructor: + TmpList.append(TAB_INF_DEFINES_CONSTRUCTOR + ' = ' + Item.Constructor) + if Item.Destructor: + TmpList.append(TAB_INF_DEFINES_DESTRUCTOR + ' = ' + Item.Destructor) + # Other define items + if Module.UserExtensions != None: + for Item in Module.UserExtensions.Defines: + TmpList.append(Item) + InfList['Defines'] = TmpList + if ModuleHeader.Description != '': + SectionHeaderCommentDict['Defines'] = ModuleHeader.Description + + if Module.UserExtensions != None: + InfList['BuildOptions'] = Module.UserExtensions.BuildOptions + + for Item in Module.Includes: + Key = 'Includes.' + GetStringOfList(Item.SupArchList) + Value = GetHelpTextList(Item.HelpTextList) + Value.append(Item.FilePath) + GenMetaDatSectionItem(Key, Value, InfList) + + for Item in Module.LibraryClasses: + Key = 'LibraryClasses.' + GetStringOfList(Item.SupArchList) + Value = GetHelpTextList(Item.HelpTextList) + NewValue = Item.LibraryClass + if Item.RecommendedInstance: + NewValue = NewValue + '|' + Item.RecommendedInstance + if Item.FeatureFlag: + NewValue = NewValue + '|' + Item.FeatureFlag + Value.append(NewValue) + GenMetaDatSectionItem(Key, Value, InfList) + + for Item in Module.PackageDependencies: + Key = 'Packages.' + GetStringOfList(Item.SupArchList) + Value = GetHelpTextList(Item.HelpTextList) + Value.append(Item.FilePath) + GenMetaDatSectionItem(Key, Value, InfList) + + for Item in Module.PcdCodes: + Key = 'Pcds' + Item.ItemType + '.' + GetStringOfList(Item.SupArchList) + Value = GetHelpTextList(Item.HelpTextList) + NewValue = Item.TokenSpaceGuidCName + '.' + Item.CName + if Item.DefaultValue != '': + NewValue = NewValue + '|' + Item.DefaultValue + Value.append(NewValue) + GenMetaDatSectionItem(Key, Value, InfList) + + for Item in Module.Sources: + Key = 'Sources.' + GetStringOfList(Item.SupArchList) + Value = GetHelpTextList(Item.HelpTextList) + NewValue = Item.SourceFile + if Item.ToolChainFamily != '': + NewValue = NewValue + '|' + Item.ToolChainFamily + if Item.TagName != '': + NewValue = NewValue + '|' + Item.TagName + if Item.ToolCode != '': + NewValue = NewValue + '|' + Item.ToolCode + if Item.FeatureFlag != '': + NewValue = NewValue + '|' + Item.FeatureFlag + Value.append(NewValue) + if Item.HelpText != '': + SectionHeaderCommentDict[Key] = Item.HelpText + GenMetaDatSectionItem(Key, Value, InfList) + + for Item in Module.Guids: + Key = 'Guids.' + GetStringOfList(Item.SupArchList) + Value = GetHelpTextList(Item.HelpTextList) + Value.append(Item.CName) + GenMetaDatSectionItem(Key, Value, InfList) + + for Item in Module.Protocols: + Key = 'Protocols.' + GetStringOfList(Item.SupArchList) + Value = GetHelpTextList(Item.HelpTextList) + Value.append(Item.CName) + GenMetaDatSectionItem(Key, Value, InfList) + + for Item in Module.Ppis: + Key = 'Ppis.' + GetStringOfList(Item.SupArchList) + Value = GetHelpTextList(Item.HelpTextList) + Value.append(Item.CName) + GenMetaDatSectionItem(Key, Value, InfList) + + if Module.PeiDepex: + Key = 'Depex' + Value = Module.PeiDepex.Depex + GenMetaDatSectionItem(Key, Value, InfList) + + if Module.DxeDepex: + Key = 'Depex' + Value = Module.DxeDepex.Depex + GenMetaDatSectionItem(Key, Value, InfList) + + if Module.SmmDepex: + Key = 'Depex' + Value = Module.SmmDepex.Depex + GenMetaDatSectionItem(Key, Value, InfList) + + for Item in Module.Binaries: + Key = 'Binaries.' + GetStringOfList(Item.SupArchList) + Value = GetHelpTextList(Item.HelpTextList) + NewValue = Item.FileType + '|' + Item.BinaryFile + '|' + Item.Target + if Item.FeatureFlag != '': + NewValue = NewValue + '|' + Item.FeatureFlag + Value.append(NewValue) + GenMetaDatSectionItem(Key, Value, InfList) + + # Transfer Module to Inf + for Key in InfList: + if Key in SectionHeaderCommentDict: + List = SectionHeaderCommentDict[Key].split('\r') + for Item in List: + Inf = Inf + Item + '\n' + Inf = Inf + '[' + Key + ']' + '\n' + for Value in InfList[Key]: + if type(Value) == type([]): + for SubValue in Value: + Inf = Inf + ' ' + SubValue + '\n' + else: + Inf = Inf + ' ' + Value + '\n' + Inf = Inf + '\n' + + return Inf + + + ## Transfer to Module Object + # + # Transfer all contents of an Inf file to a standard Module Object + # + def InfToModule(self): + # Init global information for the file + ContainerFile = self.Identification.FullPath + + # Generate Module Header + self.GenModuleHeader(ContainerFile) + + # Generate BuildOptions + self.GenBuildOptions(ContainerFile) + + # Generate Includes + self.GenIncludes(ContainerFile) + + # Generate LibraryClasses + self.GenLibraryClasses(ContainerFile) + + # Generate Packages + self.GenPackages(ContainerFile) + + # Generate Pcds + self.GenPcds(ContainerFile) + + # Generate Sources + self.GenSources(ContainerFile) + + # Generate Guids + self.GenGuidProtocolPpis(DataType.TAB_GUIDS, ContainerFile) + + # Generate Protocols + self.GenGuidProtocolPpis(DataType.TAB_PROTOCOLS, ContainerFile) + + # Generate Ppis + self.GenGuidProtocolPpis(DataType.TAB_PPIS, ContainerFile) + + # Generate Depexes + self.GenDepexes(ContainerFile) + + # Generate Binaries + self.GenBinaries(ContainerFile) + + # Init MiscFiles + self.GenMiscFiles(ContainerFile) + + ## GenMiscFiles + # + def GenMiscFiles(self, ContainerFile): + MiscFiles = MiscFileClass() + MiscFiles.Name = 'ModuleFiles' + for Item in GetFiles(os.path.dirname(ContainerFile), ['CVS', '.svn'], False): + File = CommonClass.FileClass() + File.Filename = Item + MiscFiles.Files.append(File) + self.Module.MiscFiles = MiscFiles + + ## Load Inf file + # + # Load the file if it exists + # + # @param Filename: Input value for filename of Inf file + # + def LoadInfFile(self, Filename): + # Insert a record for file + Filename = NormPath(Filename) + + self.Identification.FullPath = Filename + (self.Identification.RelaPath, self.Identification.FileName) = os.path.split(Filename) + if self.Identification.FullPath.find(self.WorkspaceDir) > -1: + self.Identification.ModulePath = os.path.dirname(self.Identification.FullPath[len(self.WorkspaceDir) + 1:]) + if self.PackageDir: + self.Identification.PackagePath = self.PackageDir + if self.Identification.ModulePath.find(self.PackageDir) == 0: + self.Identification.ModulePath = self.Identification.ModulePath[len(self.PackageDir) + 1:] + + # Init common datas + IfDefList, SectionItemList, CurrentSection, ArchList, ThirdList, IncludeFiles = \ + [], [], TAB_UNKNOWN, [], [], [] + LineNo = 0 + + # Parse file content + IsFindBlockComment = False + ReservedLine = '' + Comment = '' + for Line in open(Filename, 'r'): + LineNo = LineNo + 1 + # Remove comment block + if Line.find(TAB_COMMENT_R8_START) > -1: + ReservedLine = GetSplitValueList(Line, TAB_COMMENT_R8_START, 1)[0] + if ReservedLine.strip().startswith(TAB_COMMENT_SPLIT): + Comment = Comment + Line.strip() + '\n' + ReservedLine = '' + else: + Comment = Comment + Line[len(ReservedLine):] + '\n' + IsFindBlockComment = True + if not ReservedLine: + continue + if Line.find(TAB_COMMENT_R8_END) > -1: + Comment = Comment + Line[:Line.find(TAB_COMMENT_R8_END) + len(TAB_COMMENT_R8_END)] + '\n' + Line = ReservedLine + GetSplitValueList(Line, TAB_COMMENT_R8_END, 1)[1] + ReservedLine = '' + IsFindBlockComment = False + if IsFindBlockComment: + Comment = Comment + Line.strip() + '\n' + continue + + # Remove comments at tail and remove spaces again + if Line.strip().startswith(TAB_COMMENT_SPLIT) or Line.strip().startswith('--/'): + Comment = Comment + Line.strip() + '\n' + Line = CleanString(Line) + if Line == '': + continue + + ## Find a new section tab + # First insert previous section items + # And then parse the content of the new section + if Line.startswith(TAB_SECTION_START) and Line.endswith(TAB_SECTION_END): + if Line[1:3] == "--": + continue + Model = Section[CurrentSection.upper()] + # Insert items data of previous section + InsertSectionItems(Model, CurrentSection, SectionItemList, ArchList, ThirdList, self.RecordSet) + + # Parse the new section + SectionItemList = [] + ArchList = [] + ThirdList = [] + + CurrentSection = '' + LineList = GetSplitValueList(Line[len(TAB_SECTION_START):len(Line) - len(TAB_SECTION_END)], TAB_COMMA_SPLIT) + for Item in LineList: + ItemList = GetSplitValueList(Item, TAB_SPLIT) + if CurrentSection == '': + CurrentSection = ItemList[0] + else: + if CurrentSection != ItemList[0]: + EdkLogger.error("Parser", PARSER_ERROR, "Different section names '%s' and '%s' are found in one section definition, this is not allowed." % (CurrentSection, ItemList[0]), File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError) + if CurrentSection.upper() not in self.KeyList: + RaiseParserError(Line, CurrentSection, Filename, '', LineNo) + ItemList.append('') + ItemList.append('') + if len(ItemList) > 5: + RaiseParserError(Line, CurrentSection, Filename, '', LineNo) + else: + if ItemList[1] != '' and ItemList[1].upper() not in ARCH_LIST_FULL: + EdkLogger.error("Parser", PARSER_ERROR, "Invalid Arch definition '%s' found" % ItemList[1], File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError) + ArchList.append(ItemList[1].upper()) + ThirdList.append(ItemList[2]) + + if Comment: + if Comment.endswith('\n'): + Comment = Comment[:len(Comment) - len('\n')] + self.SectionHeaderCommentDict[Section[CurrentSection.upper()]] = Comment + Comment = '' + continue + + # Not in any defined section + if CurrentSection == TAB_UNKNOWN: + ErrorMsg = "%s is not in any defined section" % Line + EdkLogger.error("Parser", PARSER_ERROR, ErrorMsg, File=Filename, Line=LineNo, RaiseError = EdkLogger.IsRaiseError) + + # Add a section item + SectionItemList.append([Line, LineNo, Comment]) + Comment = '' + # End of parse + #End of For + + # Insert items data of last section + Model = Section[CurrentSection.upper()] + InsertSectionItems(Model, CurrentSection, SectionItemList, ArchList, ThirdList, self.RecordSet) + if Comment != '': + self.SectionHeaderCommentDict[Model] = Comment + Comment = '' + + ## Show detailed information of Module + # + # Print all members and their values of Module class + # + def ShowModule(self): + M = self.Module + print 'Filename =', M.ModuleHeader.FileName + print 'FullPath =', M.ModuleHeader.FullPath + print 'RelaPath =', M.ModuleHeader.RelaPath + print 'PackagePath =', M.ModuleHeader.PackagePath + print 'ModulePath =', M.ModuleHeader.ModulePath + print 'CombinePath =', M.ModuleHeader.CombinePath + + print 'BaseName =', M.ModuleHeader.Name + print 'Guid =', M.ModuleHeader.Guid + print 'Version =', M.ModuleHeader.Version + + print '\nIncludes =' + for Item in M.Includes: + print Item.FilePath, Item.SupArchList + print '\nLibraryClasses =' + for Item in M.LibraryClasses: + print Item.LibraryClass, Item.RecommendedInstance, Item.RecommendedInstanceGuid, Item.RecommendedInstanceVersion, Item.FeatureFlag, Item.SupModuleList, Item.SupArchList, Item.Define + print '\nPackageDependencies =' + for Item in M.PackageDependencies: + print Item.FilePath, Item.SupArchList, Item.FeatureFlag + print '\nPcds =' + for Item in M.PcdCodes: + print '\tCName=',Item.CName, 'TokenSpaceGuidCName=', Item.TokenSpaceGuidCName, 'DefaultValue=', Item.DefaultValue, 'ItemType=', Item.ItemType, Item.SupArchList + print '\nSources =' + for Source in M.Sources: + print Source.SourceFile, 'Fam=', Source.ToolChainFamily, 'Pcd=', Source.FeatureFlag, 'Tag=', Source.TagName, 'ToolCode=', Source.ToolCode, Source.SupArchList + print '\nGuids =' + for Item in M.Guids: + print Item.CName, Item.SupArchList, Item.FeatureFlag + print '\nProtocols =' + for Item in M.Protocols: + print Item.CName, Item.SupArchList, Item.FeatureFlag + print '\nPpis =' + for Item in M.Ppis: + print Item.CName, Item.SupArchList, Item.FeatureFlag + print '\nDepex =' + for Item in M.Depex: + print Item.Depex, Item.SupArchList, Item.Define + print '\nBinaries =' + for Binary in M.Binaries: + print 'Type=', Binary.FileType, 'Target=', Binary.Target, 'Name=', Binary.BinaryFile, 'FeatureFlag=', Binary.FeatureFlag, 'SupArchList=', Binary.SupArchList + print '\n*** FileList ***' + for Item in M.MiscFiles.Files: + print Item.Filename + print '****************\n' + + ## Convert [Defines] section content to ModuleHeaderClass + # + # Convert [Defines] section content to ModuleHeaderClass + # + # @param Defines The content under [Defines] section + # @param ModuleHeader An object of ModuleHeaderClass + # @param Arch The supported ARCH + # + def GenModuleHeader(self, ContainerFile): + EdkLogger.debug(2, "Generate ModuleHeader ...") + # Update all defines item in database + RecordSet = self.RecordSet[MODEL_META_DATA_HEADER] + + ModuleHeader = ModuleHeaderClass() + ModuleExtern = ModuleExternClass() + OtherDefines = [] + for Record in RecordSet: + ValueList = GetSplitValueList(Record[0], TAB_EQUAL_SPLIT) + if len(ValueList) != 2: + OtherDefines.append(Record[0]) + else: + Name = ValueList[0] + Value = ValueList[1] + if Name == TAB_INF_DEFINES_BASE_NAME: + ModuleHeader.Name = Value + ModuleHeader.BaseName = Value + elif Name == TAB_INF_DEFINES_FILE_GUID: + ModuleHeader.Guid = Value + elif Name == TAB_INF_DEFINES_VERSION_STRING: + ModuleHeader.Version = Value + elif Name == TAB_INF_DEFINES_PCD_IS_DRIVER: + ModuleHeader.PcdIsDriver = Value + elif Name == TAB_INF_DEFINES_MODULE_TYPE: + ModuleHeader.ModuleType = Value + elif Name == TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION: + ModuleHeader.UefiSpecificationVersion = Value + elif Name == TAB_INF_DEFINES_PI_SPECIFICATION_VERSION: + ModuleHeader.PiSpecificationVersion = Value + elif Name == TAB_INF_DEFINES_ENTRY_POINT: + ModuleExtern.EntryPoint = Value + elif Name == TAB_INF_DEFINES_UNLOAD_IMAGE: + ModuleExtern.UnloadImage = Value + elif Name == TAB_INF_DEFINES_CONSTRUCTOR: + ModuleExtern.Constructor = Value + elif Name == TAB_INF_DEFINES_DESTRUCTOR: + ModuleExtern.Destructor = Value + else: + OtherDefines.append(Record[0]) + ModuleHeader.FileName = self.Identification.FileName + ModuleHeader.FullPath = self.Identification.FullPath + ModuleHeader.RelaPath = self.Identification.RelaPath + ModuleHeader.PackagePath = self.Identification.PackagePath + ModuleHeader.ModulePath = self.Identification.ModulePath + ModuleHeader.CombinePath = os.path.normpath(os.path.join(ModuleHeader.PackagePath, ModuleHeader.ModulePath, ModuleHeader.FileName)) + + if MODEL_META_DATA_HEADER in self.SectionHeaderCommentDict: + ModuleHeader.Description = self.SectionHeaderCommentDict[MODEL_META_DATA_HEADER] + self.Module.ModuleHeader = ModuleHeader + self.Module.Externs.append(ModuleExtern) + UE = self.Module.UserExtensions + if UE == None: + UE = UserExtensionsClass() + UE.Defines = OtherDefines + self.Module.UserExtensions = UE + + ## GenBuildOptions + # + # Gen BuildOptions of Inf + # [:]=Flag + # + # @param ContainerFile: The Inf file full path + # + def GenBuildOptions(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_BUILD_OPTIONS) + BuildOptions = {} + # Get all BuildOptions + RecordSet = self.RecordSet[MODEL_META_DATA_BUILD_OPTION] + UE = self.Module.UserExtensions + if UE == None: + UE = UserExtensionsClass() + for Record in RecordSet: + UE.BuildOptions.append(Record[0]) + self.Module.UserExtensions = UE + + ## GenIncludes + # + # Gen Includes of Inf + # + # @param ContainerFile: The Inf file full path + # + def GenIncludes(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_INCLUDES) + Includes = sdict() + # Get all Includes + RecordSet = self.RecordSet[MODEL_EFI_INCLUDE] + for Record in RecordSet: + Include = IncludeClass() + Include.FilePath = Record[0] + Include.SupArchList = Record[1] + if GenerateHelpText(Record[5], ''): + Include.HelpTextList.append(GenerateHelpText(Record[5], '')) + self.Module.Includes.append(Include) + #self.Module.FileList.extend(GetFiles(os.path.normpath(os.path.join(self.Identification.FileRelativePath, Include.FilePath)), ['CVS', '.svn'])) + + ## GenLibraryClasses + # + # Get LibraryClass of Inf + # | + # + # @param ContainerFile: The Inf file full path + # + def GenLibraryClasses(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_LIBRARY_CLASSES) + LibraryClasses = {} + # Get all LibraryClasses + RecordSet = self.RecordSet[MODEL_EFI_LIBRARY_CLASS] + for Record in RecordSet: + (LibClassName, LibClassIns, Pcd, SupModelList) = GetLibraryClassOfInf([Record[0], Record[4]], ContainerFile, self.WorkspaceDir, Record[2]) + LibraryClass = CommonClass.LibraryClassClass() + LibraryClass.LibraryClass = LibClassName + LibraryClass.RecommendedInstance = LibClassIns + LibraryClass.FeatureFlag = Pcd + LibraryClass.SupArchList = Record[1] + LibraryClass.SupModuleList = Record[4] + if GenerateHelpText(Record[5], ''): + LibraryClass.HelpTextList.append(GenerateHelpText(Record[5], '')) + self.Module.LibraryClasses.append(LibraryClass) + + ## GenPackages + # + # Gen Packages of Inf + # + # @param ContainerFile: The Inf file full path + # + def GenPackages(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_PACKAGES) + Packages = {} + # Get all Packages + RecordSet = self.RecordSet[MODEL_META_DATA_PACKAGE] + for Record in RecordSet: + (PackagePath, Pcd) = GetPackage(Record[0], ContainerFile, self.WorkspaceDir, Record[2]) + Package = ModulePackageDependencyClass() + Package.FilePath = NormPath(PackagePath) + Package.SupArchList = Record[1] + Package.FeatureFlag = Pcd + if GenerateHelpText(Record[5], ''): + Package.HelpTextList.append(GenerateHelpText(Record[5], '')) + self.Module.PackageDependencies.append(Package) + + def AddPcd(self, CName, TokenSpaceGuidCName, DefaultValue, ItemType, Arch, HelpTextList): + Pcd = PcdClass() + Pcd.CName = CName + Pcd.TokenSpaceGuidCName = TokenSpaceGuidCName + Pcd.DefaultValue = DefaultValue + Pcd.ItemType = ItemType + Pcd.SupArchList = Arch + if GenerateHelpText(HelpTextList, ''): + Pcd.HelpTextList.append(GenerateHelpText(HelpTextList, '')) + self.Module.PcdCodes.append(Pcd) + + ## GenPcds + # + # Gen Pcds of Inf + # .[|] + # + # @param ContainerFile: The Dec file full path + # + def GenPcds(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_PCDS) + Pcds = {} + PcdToken = {} + + # Get all Pcds + RecordSet1 = self.RecordSet[MODEL_PCD_FIXED_AT_BUILD] + RecordSet2 = self.RecordSet[MODEL_PCD_PATCHABLE_IN_MODULE] + RecordSet3 = self.RecordSet[MODEL_PCD_FEATURE_FLAG] + RecordSet4 = self.RecordSet[MODEL_PCD_DYNAMIC_EX] + RecordSet5 = self.RecordSet[MODEL_PCD_DYNAMIC] + + # Go through each arch + for Record in RecordSet1: + (TokenSpaceGuidCName, TokenName, Value, Type) = GetPcdOfInf(Record[0], TAB_PCDS_FIXED_AT_BUILD, ContainerFile, Record[2]) + self.AddPcd(TokenName, TokenSpaceGuidCName, Value, Type, Record[1], Record[5]) + for Record in RecordSet2: + (TokenSpaceGuidCName, TokenName, Value, Type) = GetPcdOfInf(Record[0], TAB_PCDS_PATCHABLE_IN_MODULE, ContainerFile, Record[2]) + self.AddPcd(TokenName, TokenSpaceGuidCName, Value, Type, Record[1], Record[5]) + for Record in RecordSet3: + (TokenSpaceGuidCName, TokenName, Value, Type) = GetPcdOfInf(Record[0], TAB_PCDS_FEATURE_FLAG, ContainerFile, Record[2]) + self.AddPcd(TokenName, TokenSpaceGuidCName, Value, Type, Record[1], Record[5]) + for Record in RecordSet4: + (TokenSpaceGuidCName, TokenName, Value, Type) = GetPcdOfInf(Record[0], TAB_PCDS_DYNAMIC_EX, ContainerFile, Record[2]) + self.AddPcd(TokenName, TokenSpaceGuidCName, Value, Type, Record[1], Record[5]) + for Record in RecordSet5: + (TokenSpaceGuidCName, TokenName, Value, Type) = GetPcdOfInf(Record[0], '', ContainerFile, Record[2]) + self.AddPcd(TokenName, TokenSpaceGuidCName, Value, Type, Record[1], Record[5]) + + ## GenSources + # + # Gen Sources of Inf + # [|[|[|[|]]]] + # + # @param ContainerFile: The Dec file full path + # + def GenSources(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_SOURCES) + Sources = {} + + # Get all Sources + RecordSet = self.RecordSet[MODEL_EFI_SOURCE_FILE] + for Record in RecordSet: + (Filename, Family, TagName, ToolCode, Pcd) = GetSource(Record[0], ContainerFile, self.Identification.RelaPath, Record[2]) + Source = ModuleSourceFileClass(Filename, TagName, ToolCode, Family, Pcd, Record[1]) + if GenerateHelpText(Record[5], ''): + Source.HelpTextList.append(GenerateHelpText(Record[5], '')) + if MODEL_EFI_SOURCE_FILE in self.SectionHeaderCommentDict: + Source.HelpText = self.SectionHeaderCommentDict[MODEL_EFI_SOURCE_FILE] + self.Module.Sources.append(Source) + #self.Module.FileList.append(os.path.normpath(os.path.join(self.Identification.RelaPath, Filename))) + + ## GenDepexes + # + # Gen Depex of Inf + # + # @param ContainerFile: The Inf file full path + # + def GenDepexes(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_DEPEX) + Depex = {} + # Get all Depexes + RecordSet = self.RecordSet[MODEL_EFI_DEPEX] + DepexString = '' + for Record in RecordSet: + DepexString = DepexString + Record[0] + '\n' + Dep = ModuleDepexClass() + if DepexString.endswith('\n'): + DepexString = DepexString[:len(DepexString) - len('\n')] + Dep.Depex = DepexString + if self.Module.ModuleHeader.ModuleType in ['DXE_SMM_DRIVER']: + self.Module.SmmDepex = Dep + elif self.Module.ModuleHeader.ModuleType in ['PEI_CORE', 'PEIM']: + self.Module.PeiDepex = Dep + else: + self.Module.DxeDepex = Dep +# for Record in RecordSet: +# +# Dep = ModuleDepexClass() +# Dep.Depex = Record[0] +# Dep.SupArchList = Record[1] +# if GenerateHelpText(Record[5], ''): +# Dep.HelpTextList.append(GenerateHelpText(Record[5], '')) +# DepexString = DepexString + Dep +# List.append(Dep) +# self.Module.Depex = List +# if self.Module.ModuleHeader.ModuleType in ['DXE_SMM_DRIVER']: +# self.Module.SmmDepex = List +# elif self.Module.ModuleHeader.ModuleType in ['PEI_CORE', 'PEIM']: +# self.Module.PeiDepex = List +# else: +# self.Module.DxeDepex = List + + ## GenBinaries + # + # Gen Binary of Inf + # ||[|.] + # + # @param ContainerFile: The Dec file full path + # + def GenBinaries(self, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % TAB_BINARIES) + Binaries = {} + + # Get all Guids + RecordSet = self.RecordSet[MODEL_EFI_BINARY_FILE] + for Record in RecordSet: + (FileType, Filename, Target, Pcd) = GetBinary(Record[0], ContainerFile, self.Identification.RelaPath, Record[2]) + Binary = ModuleBinaryFileClass(Filename, FileType, Target, Pcd, Record[1]) + if GenerateHelpText(Record[5], ''): + Binary.HelpTextList.append(GenerateHelpText(Record[5], '')) + self.Module.Binaries.append(Binary) + #self.Module.FileList.append(os.path.normpath(os.path.join(self.Identification.RelaPath, Filename))) + + ## GenGuids + # + # Gen Guids of Inf + # = + # + # @param ContainerFile: The Inf file full path + # + def GenGuidProtocolPpis(self, Type, ContainerFile): + EdkLogger.debug(2, "Generate %s ..." % Type) + Lists = {} + # Get all Items + if Type == TAB_GUIDS: + ListMember = self.Module.Guids + elif Type == TAB_PROTOCOLS: + ListMember = self.Module.Protocols + elif Type == TAB_PPIS: + ListMember = self.Module.Ppis + + RecordSet = self.RecordSet[Section[Type.upper()]] + for Record in RecordSet: + (Name, Value) = GetGuidsProtocolsPpisOfInf(Record[0], Type, ContainerFile, Record[2]) + ListClass = GuidProtocolPpiCommonClass() + ListClass.CName = Name + ListClass.SupArchList = Record[1] + ListClass.FeatureFlag = Value + if GenerateHelpText(Record[5], ''): + ListClass.HelpTextList.append(GenerateHelpText(Record[5], '')) + ListMember.append(ListClass) + +## +# +# 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.QUIET) + + W = os.getenv('WORKSPACE') + F = os.path.join(W, 'MdeModulePkg/Application/HelloWorld/HelloWorld.inf') + + P = Inf(os.path.normpath(F), True, W, 'MdeModulePkg') + P.ShowModule() + print P.ModuleToInf(P.Module) diff --git a/BaseTools/Source/Python/Common/MigrationUtilities.py b/BaseTools/Source/Python/Common/MigrationUtilities.py new file mode 100644 index 0000000000..8573f0b692 --- /dev/null +++ b/BaseTools/Source/Python/Common/MigrationUtilities.py @@ -0,0 +1,567 @@ +## @file +# Contains several utilitities shared by migration tools. +# +# Copyright (c) 2007, 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 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 re +import EdkLogger +from optparse import OptionParser +from Common.BuildToolError import * +from XmlRoutines import * +from CommonDataClass.CommonClass import * + +## Set all fields of CommonClass object. +# +# Set all attributes of CommonClass object from XML Dom object of XmlCommon. +# +# @param Common The destine CommonClass object. +# @param XmlCommon The source XML Dom object. +# +def SetCommon(Common, XmlCommon): + XmlTag = "Usage" + Common.Usage = XmlAttribute(XmlCommon, XmlTag).split() + + XmlTag = "FeatureFlag" + Common.FeatureFlag = XmlAttribute(XmlCommon, XmlTag) + + XmlTag = "SupArchList" + Common.SupArchList = XmlAttribute(XmlCommon, XmlTag).split() + + XmlTag = XmlNodeName(XmlCommon) + "/" + "HelpText" + Common.HelpText = XmlElement(XmlCommon, XmlTag) + + +## Set some fields of CommonHeaderClass object. +# +# Set Name, Guid, FileName and FullPath fields of CommonHeaderClass object from +# XML Dom object of XmlCommonHeader, NameTag and FileName. +# +# @param CommonHeader The destine CommonClass object. +# @param XmlCommonHeader The source XML Dom object. +# @param NameTag The name tag in XML Dom object. +# @param FileName The file name of the XML file. +# +def SetIdentification(CommonHeader, XmlCommonHeader, NameTag, FileName): + XmlParentTag = XmlNodeName(XmlCommonHeader) + + XmlTag = XmlParentTag + "/" + NameTag + CommonHeader.Name = XmlElement(XmlCommonHeader, XmlTag) + + XmlTag = XmlParentTag + "/" + "GuidValue" + CommonHeader.Guid = XmlElement(XmlCommonHeader, XmlTag) + + XmlTag = XmlParentTag + "/" + "Version" + CommonHeader.Version = XmlElement(XmlCommonHeader, XmlTag) + + CommonHeader.FileName = os.path.basename(FileName) + CommonHeader.FullPath = os.path.abspath(FileName) + + +## Regular expression to match specification and value. +mReSpecification = re.compile(r"(?P\w+)\s+(?P\w*)") + +## Add specification to specification dictionary. +# +# Abstract specification name, value pair from Specification String and add them +# to specification dictionary. +# +# @param SpecificationDict The destine Specification dictionary. +# @param SpecificationString The source Specification String from which the +# specification name and value pair is abstracted. +# +def AddToSpecificationDict(SpecificationDict, SpecificationString): + """Abstract specification name, value pair from Specification String""" + for SpecificationMatch in mReSpecification.finditer(SpecificationString): + Specification = SpecificationMatch.group("Specification") + Value = SpecificationMatch.group("Value") + SpecificationDict[Specification] = Value + +## Set all fields of CommonHeaderClass object. +# +# Set all attributes of CommonHeaderClass object from XML Dom object of +# XmlCommonHeader, NameTag and FileName. +# +# @param CommonHeader The destine CommonClass object. +# @param XmlCommonHeader The source XML Dom object. +# @param NameTag The name tag in XML Dom object. +# @param FileName The file name of the XML file. +# +def SetCommonHeader(CommonHeader, XmlCommonHeader): + """Set all attributes of CommonHeaderClass object from XmlCommonHeader""" + XmlParent = XmlNodeName(XmlCommonHeader) + + XmlTag = XmlParent + "/" + "Abstract" + CommonHeader.Abstract = XmlElement(XmlCommonHeader, XmlTag) + + XmlTag = XmlParent + "/" + "Description" + CommonHeader.Description = XmlElement(XmlCommonHeader, XmlTag) + + XmlTag = XmlParent + "/" + "Copyright" + CommonHeader.Copyright = XmlElement(XmlCommonHeader, XmlTag) + + XmlTag = XmlParent + "/" + "License" + CommonHeader.License = XmlElement(XmlCommonHeader, XmlTag) + + XmlTag = XmlParent + "/" + "Specification" + Specification = XmlElement(XmlCommonHeader, XmlTag) + + AddToSpecificationDict(CommonHeader.Specification, Specification) + + XmlTag = XmlParent + "/" + "ModuleType" + CommonHeader.ModuleType = XmlElement(XmlCommonHeader, XmlTag) + + +## Load a new Cloned Record class object. +# +# Read an input XML ClonedRecord DOM object and return an object of Cloned Record +# contained in the DOM object. +# +# @param XmlCloned A child XML DOM object in a Common XML DOM. +# +# @retvel ClonedRecord A new Cloned Record object created by XmlCloned. +# +def LoadClonedRecord(XmlCloned): + ClonedRecord = ClonedRecordClass() + + XmlTag = "Id" + ClonedRecord.Id = int(XmlAttribute(XmlCloned, XmlTag)) + + XmlTag = "FarGuid" + ClonedRecord.FarGuid = XmlAttribute(XmlCloned, XmlTag) + + XmlTag = "Cloned/PackageGuid" + ClonedRecord.PackageGuid = XmlElement(XmlCloned, XmlTag) + + XmlTag = "Cloned/PackageVersion" + ClonedRecord.PackageVersion = XmlElement(XmlCloned, XmlTag) + + XmlTag = "Cloned/ModuleGuid" + ClonedRecord.ModuleGuid = XmlElement(XmlCloned, XmlTag) + + XmlTag = "Cloned/ModuleVersion" + ClonedRecord.ModuleVersion = XmlElement(XmlCloned, XmlTag) + + return ClonedRecord + + +## Load a new Guid/Protocol/Ppi common class object. +# +# Read an input XML Guid/Protocol/Ppi DOM object and return an object of +# Guid/Protocol/Ppi contained in the DOM object. +# +# @param XmlGuidProtocolPpiCommon A child XML DOM object in a Common XML DOM. +# +# @retvel GuidProtocolPpiCommon A new GuidProtocolPpiCommon class object +# created by XmlGuidProtocolPpiCommon. +# +def LoadGuidProtocolPpiCommon(XmlGuidProtocolPpiCommon): + GuidProtocolPpiCommon = GuidProtocolPpiCommonClass() + + XmlTag = "Name" + GuidProtocolPpiCommon.Name = XmlAttribute(XmlGuidProtocolPpiCommon, XmlTag) + + XmlParent = XmlNodeName(XmlGuidProtocolPpiCommon) + if XmlParent == "Entry": + XmlTag = "%s/C_Name" % XmlParent + elif XmlParent == "GuidCNames": + XmlTag = "%s/GuidCName" % XmlParent + else: + XmlTag = "%s/%sCName" % (XmlParent, XmlParent) + + GuidProtocolPpiCommon.CName = XmlElement(XmlGuidProtocolPpiCommon, XmlTag) + + XmlTag = XmlParent + "/" + "GuidValue" + GuidProtocolPpiCommon.Guid = XmlElement(XmlGuidProtocolPpiCommon, XmlTag) + + if XmlParent.endswith("Notify"): + GuidProtocolPpiCommon.Notify = True + + XmlTag = "GuidTypeList" + GuidTypes = XmlAttribute(XmlGuidProtocolPpiCommon, XmlTag) + GuidProtocolPpiCommon.GuidTypeList = GuidTypes.split() + + XmlTag = "SupModuleList" + SupModules = XmlAttribute(XmlGuidProtocolPpiCommon, XmlTag) + GuidProtocolPpiCommon.SupModuleList = SupModules.split() + + SetCommon(GuidProtocolPpiCommon, XmlGuidProtocolPpiCommon) + + return GuidProtocolPpiCommon + + +## Load a new Pcd class object. +# +# Read an input XML Pcd DOM object and return an object of Pcd +# contained in the DOM object. +# +# @param XmlPcd A child XML DOM object in a Common XML DOM. +# +# @retvel Pcd A new Pcd object created by XmlPcd. +# +def LoadPcd(XmlPcd): + """Return a new PcdClass object equivalent to XmlPcd""" + Pcd = PcdClass() + + XmlTag = "PcdEntry/C_Name" + Pcd.CName = XmlElement(XmlPcd, XmlTag) + + XmlTag = "PcdEntry/Token" + Pcd.Token = XmlElement(XmlPcd, XmlTag) + + XmlTag = "PcdEntry/TokenSpaceGuidCName" + Pcd.TokenSpaceGuidCName = XmlElement(XmlPcd, XmlTag) + + XmlTag = "PcdEntry/DatumType" + Pcd.DatumType = XmlElement(XmlPcd, XmlTag) + + XmlTag = "PcdEntry/MaxDatumSize" + Pcd.MaxDatumSize = XmlElement(XmlPcd, XmlTag) + + XmlTag = "PcdEntry/DefaultValue" + Pcd.DefaultValue = XmlElement(XmlPcd, XmlTag) + + XmlTag = "PcdItemType" + Pcd.ItemType = XmlAttribute(XmlPcd, XmlTag) + + XmlTag = "PcdEntry/ValidUsage" + Pcd.ValidUsage = XmlElement(XmlPcd, XmlTag).split() + + XmlTag = "SupModuleList" + Pcd.SupModuleList = XmlAttribute(XmlPcd, XmlTag).split() + + SetCommon(Pcd, XmlPcd) + + return Pcd + + +## Load a new LibraryClass class object. +# +# Read an input XML LibraryClass DOM object and return an object of LibraryClass +# contained in the DOM object. +# +# @param XmlLibraryClass A child XML DOM object in a Common XML DOM. +# +# @retvel LibraryClass A new LibraryClass object created by XmlLibraryClass. +# +def LoadLibraryClass(XmlLibraryClass): + LibraryClass = LibraryClassClass() + + XmlTag = "LibraryClass/Keyword" + LibraryClass.LibraryClass = XmlElement(XmlLibraryClass, XmlTag) + if LibraryClass.LibraryClass == "": + XmlTag = "Name" + LibraryClass.LibraryClass = XmlAttribute(XmlLibraryClass, XmlTag) + + XmlTag = "LibraryClass/IncludeHeader" + LibraryClass.IncludeHeader = XmlElement(XmlLibraryClass, XmlTag) + + XmlTag = "RecommendedInstanceVersion" + RecommendedInstanceVersion = XmlAttribute(XmlLibraryClass, XmlTag) + LibraryClass.RecommendedInstanceVersion = RecommendedInstanceVersion + + XmlTag = "RecommendedInstanceGuid" + RecommendedInstanceGuid = XmlAttribute(XmlLibraryClass, XmlTag) + LibraryClass.RecommendedInstanceGuid = RecommendedInstanceGuid + + XmlTag = "SupModuleList" + SupModules = XmlAttribute(XmlLibraryClass, XmlTag) + LibraryClass.SupModuleList = SupModules.split() + + SetCommon(LibraryClass, XmlLibraryClass) + + return LibraryClass + + +## Load a new Build Option class object. +# +# Read an input XML BuildOption DOM object and return an object of Build Option +# contained in the DOM object. +# +# @param XmlBuildOption A child XML DOM object in a Common XML DOM. +# +# @retvel BuildOption A new Build Option object created by XmlBuildOption. +# +def LoadBuildOption(XmlBuildOption): + """Return a new BuildOptionClass object equivalent to XmlBuildOption""" + BuildOption = BuildOptionClass() + + BuildOption.Option = XmlElementData(XmlBuildOption) + + XmlTag = "BuildTargets" + BuildOption.BuildTargetList = XmlAttribute(XmlBuildOption, XmlTag).split() + + XmlTag = "ToolChainFamily" + BuildOption.ToolChainFamily = XmlAttribute(XmlBuildOption, XmlTag) + + XmlTag = "TagName" + BuildOption.TagName = XmlAttribute(XmlBuildOption, XmlTag) + + XmlTag = "ToolCode" + BuildOption.ToolCode = XmlAttribute(XmlBuildOption, XmlTag) + + XmlTag = "SupArchList" + BuildOption.SupArchList = XmlAttribute(XmlBuildOption, XmlTag).split() + + return BuildOption + + +## Load a new User Extensions class object. +# +# Read an input XML UserExtensions DOM object and return an object of User +# Extensions contained in the DOM object. +# +# @param XmlUserExtensions A child XML DOM object in a Common XML DOM. +# +# @retvel UserExtensions A new User Extensions object created by +# XmlUserExtensions. +# +def LoadUserExtensions(XmlUserExtensions): + UserExtensions = UserExtensionsClass() + + XmlTag = "UserID" + UserExtensions.UserID = XmlAttribute(XmlUserExtensions, XmlTag) + + XmlTag = "Identifier" + UserExtensions.Identifier = XmlAttribute(XmlUserExtensions, XmlTag) + + UserExtensions.Content = XmlElementData(XmlUserExtensions) + + return UserExtensions + + +## Store content to a text file object. +# +# Write some text file content to a text file object. The contents may echo +# in screen in a verbose way. +# +# @param TextFile The text file object. +# @param Content The string object to be written to a text file. +# +def StoreTextFile(TextFile, Content): + EdkLogger.verbose(Content) + TextFile.write(Content) + + +## Add item to a section. +# +# Add an Item with specific CPU architecture to section dictionary. +# The possible duplication is ensured to be removed. +# +# @param Section Section dictionary indexed by CPU architecture. +# @param Arch CPU architecture: Ia32, X64, Ipf, ARM, Ebc or Common. +# @param Item The Item to be added to section dictionary. +# +def AddToSection(Section, Arch, Item): + SectionArch = Section.get(Arch, []) + if Item not in SectionArch: + SectionArch.append(Item) + Section[Arch] = SectionArch + + +## Get section contents. +# +# Return the content of section named SectionName. +# the contents is based on Methods and ObjectLists. +# +# @param SectionName The name of the section. +# @param Method A function returning a string item of an object. +# @param ObjectList The list of object. +# +# @retval Section The string content of a section. +# +def GetSection(SectionName, Method, ObjectList): + SupportedArches = ["common", "Ia32", "X64", "Ipf", "Ebc", "ARM"] + SectionDict = {} + for Object in ObjectList: + Item = Method(Object) + if Item == "": + continue + Item = " %s" % Item + Arches = Object.SupArchList + if len(Arches) == 0: + AddToSection(SectionDict, "common", Item) + else: + for Arch in SupportedArches: + if Arch.upper() in Arches: + AddToSection(SectionDict, Arch, Item) + + Section = "" + for Arch in SupportedArches: + SectionArch = "\n".join(SectionDict.get(Arch, [])) + if SectionArch != "": + Section += "[%s.%s]\n%s\n" % (SectionName, Arch, SectionArch) + Section += "\n" + if Section != "": + Section += "\n" + return Section + + +## Store file header to a text file. +# +# Write standard file header to a text file. The content includes copyright, +# abstract, description and license extracted from CommonHeader class object. +# +# @param TextFile The text file object. +# @param CommonHeader The source CommonHeader class object. +# +def StoreHeader(TextFile, CommonHeader): + CopyRight = CommonHeader.Copyright + Abstract = CommonHeader.Abstract + Description = CommonHeader.Description + License = CommonHeader.License + + Header = "#/** @file\n#\n" + Header += "# " + Abstract + "\n#\n" + Header += "# " + Description.strip().replace("\n", "\n# ") + "\n" + Header += "# " + CopyRight + "\n#\n" + Header += "# " + License.replace("\n", "\n# ").replace(" ", " ") + Header += "\n#\n#**/\n\n" + + StoreTextFile(TextFile, Header) + +## Store file header to a text file. +# +# Write Defines section to a text file. DefinesTupleList determines the content. +# +# @param TextFile The text file object. +# @param DefinesTupleList The list of (Tag, Value) to be added as one item. +# +def StoreDefinesSection(TextFile, DefinesTupleList): + Section = "[Defines]\n" + for DefineItem in DefinesTupleList: + Section += " %-30s = %s\n" % DefineItem + + Section += "\n\n" + StoreTextFile(TextFile, Section) + + +## Return one User Extension section. +# +# Read the input UserExtentsions class object and return one section. +# +# @param UserExtensions An input UserExtensions class object. +# +# @retval UserExtensionSection A section representing UserExtensions object. +# +def GetUserExtensions(UserExtensions): + UserId = UserExtensions.UserID + Identifier = UserExtensions.Identifier + Content = UserExtensions.Content + + return "[UserExtensions.%s.%s]\n %s\n\n" % (UserId, Identifier, Content) + +## Regular expression to match an equation. +mReEquation = re.compile(r"\s*(\S+)\s*=\s*(\S*)\s*") + +## Return a value tuple matching information in a text fle. +# +# Parse the text file and return a value tuple corresponding to an input tag +# tuple. In case of any error, an tuple of empty strings is returned. +# +# @param FileName The file name of the text file. +# @param TagTuple A tuple of tags as the key to the value. +# +# @param ValueTupe The returned tuple corresponding to the tag tuple. +# +def GetTextFileInfo(FileName, TagTuple): + ValueTuple = [""] * len(TagTuple) + try: + for Line in open(FileName): + Line = Line.split("#", 1)[0] + MatchEquation = mReEquation.match(Line) + if MatchEquation: + Tag = MatchEquation.group(1).upper() + Value = MatchEquation.group(2) + for Index in range(len(TagTuple)): + if TagTuple[Index] == Tag: + ValueTuple[Index] = Value + except: + EdkLogger.info("IO Error in reading file %s" % FileName) + + return ValueTuple + + +## Return a value tuple matching information in an XML fle. +# +# Parse the XML file and return a value tuple corresponding to an input tag +# tuple. In case of any error, an tuple of empty strings is returned. +# +# @param FileName The file name of the XML file. +# @param TagTuple A tuple of tags as the key to the value. +# +# @param ValueTupe The returned tuple corresponding to the tag tuple. +# +def GetXmlFileInfo(FileName, TagTuple): + XmlDom = XmlParseFile(FileName) + return tuple([XmlElement(XmlDom, XmlTag) for XmlTag in TagTuple]) + + +## Parse migration command line options +# +# Use standard Python module optparse to parse command line option of this tool. +# +# @param Source The source file type. +# @param Destinate The destinate file type. +# +# @retval Options A optparse object containing the parsed options. +# @retval InputFile Path of an source file to be migrated. +# +def MigrationOptionParser(Source, Destinate, ToolName, VersionNumber = 1.0): + # use clearer usage to override default usage message + UsageString = "%s [-a] [-v|-q] [-o ] " % ToolName + Version = "%s Version %.2f" % (ToolName, VersionNumber) + Copyright = "Copyright (c) 2007, Intel Corporation. All rights reserved." + + Parser = OptionParser(description=Copyright, version=Version, usage=UsageString) + Parser.add_option("-o", "--output", dest="OutputFile", help="The name of the %s file to be created." % Destinate) + Parser.add_option("-a", "--auto", dest="AutoWrite", action="store_true", default=False, help="Automatically create the %s file using the name of the %s file and replacing file extension" % (Source, Destinate)) + Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.") + Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed.") + + Options, Args = Parser.parse_args() + + # Set logging level + if Options.verbose: + EdkLogger.setLevel(EdkLogger.VERBOSE) + elif Options.quiet: + EdkLogger.setLevel(EdkLogger.QUIET) + else: + EdkLogger.setLevel(EdkLogger.INFO) + + # error check + if len(Args) == 0: + raise MigrationError(PARAMETER_MISSING, name="Input file", usage=Parser.get_usage()) + if len(Args) > 1: + raise MigrationError(PARAMETER_INVALID, name="Too many input files", usage=Parser.get_usage()) + + InputFile = Args[0] + if not os.path.exists(InputFile): + raise MigrationError(FILE_NOT_FOUND, name=InputFile) + + if Options.OutputFile: + if Options.AutoWrite: + raise MigrationError(OPTION_CONFLICT, arg1="-o", arg2="-a", usage=Parser.get_usage()) + else: + if Options.AutoWrite: + Options.OutputFile = os.path.splitext(InputFile)[0] + "." + Destinate.lower() + else: + raise MigrationError(OPTION_MISSING, name="-o", usage=Parser.get_usage()) + + return Options, InputFile + +# This acts like the main() function for the script, unless it is 'import'ed +# into another script. +if __name__ == '__main__': + pass diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py new file mode 100644 index 0000000000..14f6550f29 --- /dev/null +++ b/BaseTools/Source/Python/Common/Misc.py @@ -0,0 +1,1327 @@ +## @file +# Common routines used by all tools +# +# Copyright (c) 2007, 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 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 string +import thread +import threading +import time +import re +import cPickle +from UserDict import IterableUserDict +from UserList import UserList + +from Common import EdkLogger as EdkLogger +from Common import GlobalData as GlobalData + +from BuildToolError import * + +## Regular expression used to find out place holders in string template +gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE|re.UNICODE) + +## Dictionary used to store file time stamp for quick re-access +gFileTimeStampCache = {} # {file path : file time stamp} + +## Dictionary used to store dependencies of files +gDependencyDatabase = {} # arch : {file path : [dependent files list]} + +## callback routine for processing variable option +# +# This function can be used to process variable number of option values. The +# typical usage of it is specify architecure list on command line. +# (e.g. -a IA32 X64 IPF) +# +# @param Option Standard callback function parameter +# @param OptionString Standard callback function parameter +# @param Value Standard callback function parameter +# @param Parser Standard callback function parameter +# +# @retval +# +def ProcessVariableArgument(Option, OptionString, Value, Parser): + assert Value is None + Value = [] + RawArgs = Parser.rargs + while RawArgs: + Arg = RawArgs[0] + if (Arg[:2] == "--" and len(Arg) > 2) or \ + (Arg[:1] == "-" and len(Arg) > 1 and Arg[1] != "-"): + break + Value.append(Arg) + del RawArgs[0] + setattr(Parser.values, Option.dest, Value) + +## Convert GUID string in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx style to C structure style +# +# @param Guid The GUID string +# +# @retval string The GUID string in C structure style +# +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 + +## Convert GUID structure in byte array to xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +# +# @param GuidValue The GUID value in byte array +# +# @retval string The GUID value in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format +# +def GuidStructureByteArrayToGuidString(GuidValue): + guidValueString = GuidValue.lower().replace("{", "").replace("}", "").replace(" ", "").replace(";", "") + guidValueList = guidValueString.split(",") + if len(guidValueList) != 16: + return '' + #EdkLogger.error(None, None, "Invalid GUID value string %s" % GuidValue) + try: + return "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" % ( + int(guidValueList[3], 16), + int(guidValueList[2], 16), + int(guidValueList[1], 16), + int(guidValueList[0], 16), + int(guidValueList[5], 16), + int(guidValueList[4], 16), + int(guidValueList[7], 16), + int(guidValueList[6], 16), + int(guidValueList[8], 16), + int(guidValueList[9], 16), + int(guidValueList[10], 16), + int(guidValueList[11], 16), + int(guidValueList[12], 16), + int(guidValueList[13], 16), + int(guidValueList[14], 16), + int(guidValueList[15], 16) + ) + except: + return '' + +## Convert GUID string in C structure style to xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +# +# @param GuidValue The GUID value in C structure format +# +# @retval string The GUID value in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format +# +def GuidStructureStringToGuidString(GuidValue): + guidValueString = GuidValue.lower().replace("{", "").replace("}", "").replace(" ", "").replace(";", "") + guidValueList = guidValueString.split(",") + if len(guidValueList) != 11: + return '' + #EdkLogger.error(None, None, "Invalid GUID value string %s" % GuidValue) + 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: + return '' + +## Convert GUID string in C structure style to xxxxxxxx_xxxx_xxxx_xxxx_xxxxxxxxxxxx +# +# @param GuidValue The GUID value in C structure format +# +# @retval string The GUID value in xxxxxxxx_xxxx_xxxx_xxxx_xxxxxxxxxxxx format +# +def GuidStructureStringToGuidValueName(GuidValue): + guidValueString = GuidValue.lower().replace("{", "").replace("}", "").replace(" ", "") + guidValueList = guidValueString.split(",") + if len(guidValueList) != 11: + EdkLogger.error(None, None, "Invalid GUID value string %s" % GuidValue) + 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) + ) + +## Create directories +# +# @param Directory The directory name +# +def CreateDirectory(Directory): + if Directory == None or Directory.strip() == "": + return True + try: + if not os.access(Directory, os.F_OK): + os.makedirs(Directory) + except: + 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 = os.getcwd() + os.chdir(Directory) + for File in os.listdir("."): + if os.path.isdir(File): + RemoveDirectory(File, Recursively) + else: + os.remove(File) + os.chdir(CurrentDirectory) + os.rmdir(Directory) + +## Check if given file is changed or not +# +# This method is used to check if a file is changed or not between two build +# actions. It makes use a cache to store files timestamp. +# +# @param File The path of file +# +# @retval True If the given file is changed, doesn't exist, or can't be +# found in timestamp cache +# @retval False If the given file is changed +# +def IsChanged(File): + if not os.path.exists(File): + return True + + FileState = os.stat(File) + TimeStamp = FileState[-2] + + if File in gFileTimeStampCache and TimeStamp == gFileTimeStampCache[File]: + FileChanged = False + else: + FileChanged = True + gFileTimeStampCache[File] = TimeStamp + + return FileChanged + +## 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 +# +# @retval True If the file content is changed and the file is renewed +# @retval False If the file content is the same +# +def SaveFileOnChange(File, Content, IsBinaryFile=True): + if not IsBinaryFile: + Content = Content.replace("\n", os.linesep) + + if os.path.exists(File): + try: + if Content == open(File, "rb").read(): + return False + except: + EdkLogger.error(None, FILE_OPEN_FAILURE, ExtraData=File) + + CreateDirectory(os.path.dirname(File)) + try: + if GlobalData.gIsWindows: + try: + from PyUtility import SaveFileToDisk + if not SaveFileToDisk(File, Content): + EdkLogger.error(None, FILE_CREATE_FAILURE, ExtraData=File) + except: + Fd = open(File, "wb") + Fd.write(Content) + Fd.close() + else: + Fd = open(File, "wb") + Fd.write(Content) + Fd.close() + except: + EdkLogger.error(None, FILE_CREATE_FAILURE, ExtraData=File) + + return True + +## Make a Python object persistent on file system +# +# @param Data The object to be stored in file +# @param File The path of file to store the object +# +def DataDump(Data, File): + Fd = None + try: + Fd = open(File, 'wb') + cPickle.dump(Data, Fd, cPickle.HIGHEST_PROTOCOL) + except: + EdkLogger.error("", FILE_OPEN_FAILURE, ExtraData=File, RaiseError=False) + finally: + if Fd != None: + Fd.close() + +## Restore a Python object from a file +# +# @param File The path of file stored the object +# +# @retval object A python object +# @retval None If failure in file operation +# +def DataRestore(File): + Data = None + Fd = None + try: + Fd = open(File, 'rb') + Data = cPickle.load(Fd) + except Exception, e: + EdkLogger.verbose("Failed to load [%s]\n\t%s" % (File, str(e))) + Data = None + finally: + if Fd != None: + Fd.close() + return Data + +## Retrieve and cache the real path name in file system +# +# @param Root The root directory of path relative to +# +# @retval str The path string if the path exists +# @retval None If path doesn't exist +# +class DirCache: + _CACHE_ = {} + + def __init__(self, Root): + self._Root = Root + for F in os.listdir(Root): + self._CACHE_[F.upper()] = F + + # =[] operator + def __getitem__(self, Path): + Path = Path[len(os.path.commonprefix([Path, self._Root])):] + if not Path: + return self._Root + if Path and Path[0] == os.path.sep: + Path = Path[1:] + Path = Path.upper() + if Path in self._CACHE_: + return os.path.join(self._Root, self._CACHE_[Path]) + + IndexList = [] + LastSepIndex = -1 + SepIndex = Path.find(os.path.sep) + while SepIndex > -1: + Parent = Path[:SepIndex] + if Parent not in self._CACHE_: + break + LastSepIndex = SepIndex + SepIndex = Path.find(os.path.sep, LastSepIndex + 1) + + if LastSepIndex == -1: + return None + + Cwd = os.getcwd() + os.chdir(self._Root) + SepIndex = LastSepIndex + while SepIndex > -1: + ParentKey = Path[:SepIndex] + if ParentKey not in self._CACHE_: + os.chdir(Cwd) + return None + + ParentDir = self._CACHE_[ParentKey] + for F in os.listdir(ParentDir): + Dir = os.path.join(ParentDir, F) + self._CACHE_[Dir.upper()] = Dir + + SepIndex = Path.find(os.path.sep, SepIndex + 1) + + os.chdir(Cwd) + if Path not in self._CACHE_: + return None + return os.path.join(self._Root, self._CACHE_[Path]) + +## Get all files of a directory +# +# @param Root: Root dir +# @param SkipList : The files need be skipped +# +# @retval A list of all files +# +def GetFiles(Root, SkipList=None, FullPath = True): + OriPath = Root + FileList = [] + for Root, Dirs, Files in os.walk(Root): + if SkipList: + for Item in SkipList: + if Item in Dirs: + Dirs.remove(Item) + + for File in Files: + File = os.path.normpath(os.path.join(Root, File)) + if not FullPath: + File = File[len(OriPath) + 1:] + FileList.append(File) + + return FileList + +## Check if gvien file exists or not +# +# @param File File name or path to be checked +# @param Dir The directory the file is relative to +# +# @retval True if file exists +# @retval False if file doesn't exists +# +def ValidFile(File, Ext=None): + if Ext != None: + Dummy, FileExt = os.path.splitext(File) + if FileExt.lower() != Ext.lower(): + return False + if not os.path.exists(File): + return False + return True + +def RealPath(File, Dir='', OverrideDir=''): + NewFile = os.path.normpath(os.path.join(Dir, File)) + NewFile = GlobalData.gAllFiles[NewFile] + if not NewFile and OverrideDir: + NewFile = os.path.normpath(os.path.join(OverrideDir, File)) + NewFile = GlobalData.gAllFiles[NewFile] + return NewFile + +def RealPath2(File, Dir='', OverrideDir=''): + NewFile = GlobalData.gAllFiles[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, '' + + if OverrideDir: + NewFile = GlobalData.gAllFiles[os.path.normpath(os.path.join(OverrideDir, File))] + if NewFile: + return NewFile[len(OverrideDir)+1:], NewFile[0:len(OverrideDir)] + return None, None + +## Check if gvien file exists or not +# +# +def ValidFile2(AllFiles, File, Ext=None, Workspace='', EfiSource='', EdkSource='', Dir='.', OverrideDir=''): + NewFile = File + if Ext != None: + Dummy, FileExt = os.path.splitext(File) + if FileExt.lower() != Ext.lower(): + return False, File + + # Replace the R8 macros + if OverrideDir != '' and OverrideDir != None: + if OverrideDir.find('$(EFI_SOURCE)') > -1: + OverrideDir = OverrideDir.replace('$(EFI_SOURCE)', EfiSource) + if OverrideDir.find('$(EDK_SOURCE)') > -1: + OverrideDir = OverrideDir.replace('$(EDK_SOURCE)', EdkSource) + + # Replace the default dir to current dir + if Dir == '.': + Dir = os.getcwd() + Dir = Dir[len(Workspace)+1:] + + # First check if File has R8 definition itself + if File.find('$(EFI_SOURCE)') > -1 or File.find('$(EDK_SOURCE)') > -1: + NewFile = File.replace('$(EFI_SOURCE)', EfiSource) + NewFile = NewFile.replace('$(EDK_SOURCE)', EdkSource) + NewFile = AllFiles[os.path.normpath(NewFile)] + if NewFile != None: + return True, NewFile + + # Second check the path with override value + if OverrideDir != '' and OverrideDir != None: + NewFile = AllFiles[os.path.normpath(os.path.join(OverrideDir, File))] + if NewFile != None: + return True, NewFile + + # Last check the path with normal definitions + File = os.path.join(Dir, File) + NewFile = AllFiles[os.path.normpath(File)] + if NewFile != None: + return True, NewFile + + return False, File + +## Check if gvien file exists or not +# +# +def ValidFile3(AllFiles, File, Workspace='', EfiSource='', EdkSource='', Dir='.', OverrideDir=''): + # Replace the R8 macros + if OverrideDir != '' and OverrideDir != None: + if OverrideDir.find('$(EFI_SOURCE)') > -1: + OverrideDir = OverrideDir.replace('$(EFI_SOURCE)', EfiSource) + if OverrideDir.find('$(EDK_SOURCE)') > -1: + OverrideDir = OverrideDir.replace('$(EDK_SOURCE)', EdkSource) + + # Replace the default dir to current dir + # Dir is current module dir related to workspace + if Dir == '.': + Dir = os.getcwd() + Dir = Dir[len(Workspace)+1:] + + NewFile = File + RelaPath = AllFiles[os.path.normpath(Dir)] + NewRelaPath = RelaPath + + while(True): + # First check if File has R8 definition itself + if File.find('$(EFI_SOURCE)') > -1 or File.find('$(EDK_SOURCE)') > -1: + File = File.replace('$(EFI_SOURCE)', EfiSource) + File = File.replace('$(EDK_SOURCE)', EdkSource) + NewFile = AllFiles[os.path.normpath(File)] + if NewFile != None: + NewRelaPath = os.path.dirname(NewFile) + File = os.path.basename(NewFile) + #NewRelaPath = NewFile[:len(NewFile) - len(File.replace("..\\", '').replace("../", '')) - 1] + break + + # Second check the path with override value + if OverrideDir != '' and OverrideDir != None: + NewFile = AllFiles[os.path.normpath(os.path.join(OverrideDir, File))] + if NewFile != None: + #NewRelaPath = os.path.dirname(NewFile) + NewRelaPath = NewFile[:len(NewFile) - len(File.replace("..\\", '').replace("../", '')) - 1] + break + + # Last check the path with normal definitions + NewFile = AllFiles[os.path.normpath(os.path.join(Dir, File))] + if NewFile != None: + break + + # No file found + break + + return NewRelaPath, RelaPath, File + + +def GetRelPath(Path1, Path2): + FileName = os.path.basename(Path2) + L1 = os.path.normpath(Path1).split(os.path.normpath('/')) + L2 = os.path.normpath(Path2).split(os.path.normpath('/')) + for Index in range(0, len(L1)): + if L1[Index] != L2[Index]: + FileName = '../' * (len(L1) - Index) + for Index2 in range(Index, len(L2)): + FileName = os.path.join(FileName, L2[Index2]) + break + return os.path.normpath(FileName) + + +## Get GUID value from given packages +# +# @param CName The CName of the GUID +# @param PackageList List of packages looking-up in +# +# @retval GuidValue if the CName is found in any given package +# @retval None if the CName is not found in all given packages +# +def GuidValue(CName, PackageList): + for P in PackageList: + if CName in P.Guids: + return P.Guids[CName] + return None + +## Get Protocol value from given packages +# +# @param CName The CName of the GUID +# @param PackageList List of packages looking-up in +# +# @retval GuidValue if the CName is found in any given package +# @retval None if the CName is not found in all given packages +# +def ProtocolValue(CName, PackageList): + for P in PackageList: + if CName in P.Protocols: + return P.Protocols[CName] + return None + +## Get PPI value from given packages +# +# @param CName The CName of the GUID +# @param PackageList List of packages looking-up in +# +# @retval GuidValue if the CName is found in any given package +# @retval None if the CName is not found in all given packages +# +def PpiValue(CName, PackageList): + for P in PackageList: + if CName in P.Ppis: + return P.Ppis[CName] + return None + +## A string template class +# +# This class implements a template for string replacement. A string template +# looks like following +# +# ${BEGIN} other_string ${placeholder_name} other_string ${END} +# +# The string between ${BEGIN} and ${END} will be repeated as many times as the +# length of "placeholder_name", which is a list passed through a dict. The +# "placeholder_name" is the key name of the dict. The ${BEGIN} and ${END} can +# be not used and, in this case, the "placeholder_name" must not a list and it +# will just be replaced once. +# +class TemplateString(object): + _REPEAT_START_FLAG = "BEGIN" + _REPEAT_END_FLAG = "END" + + class Section(object): + _LIST_TYPES = [type([]), type(set()), type((0,))] + + def __init__(self, TemplateSection, PlaceHolderList): + self._Template = TemplateSection + self._PlaceHolderList = [] + + # Split the section into sub-sections according to the position of placeholders + if PlaceHolderList: + self._SubSectionList = [] + SubSectionStart = 0 + # + # The placeholders passed in must be in the format of + # + # PlaceHolderName, PlaceHolderStartPoint, PlaceHolderEndPoint + # + for PlaceHolder,Start,End in PlaceHolderList: + self._SubSectionList.append(TemplateSection[SubSectionStart:Start]) + self._SubSectionList.append(TemplateSection[Start:End]) + self._PlaceHolderList.append(PlaceHolder) + SubSectionStart = End + if SubSectionStart < len(TemplateSection): + self._SubSectionList.append(TemplateSection[SubSectionStart:]) + else: + self._SubSectionList = [TemplateSection] + + def __str__(self): + return self._Template + " : " + str(self._PlaceHolderList) + + def Instantiate(self, PlaceHolderValues): + RepeatTime = -1 + RepeatPlaceHolders = {} + NonRepeatPlaceHolders = {} + + for PlaceHolder in self._PlaceHolderList: + if PlaceHolder not in PlaceHolderValues: + continue + Value = PlaceHolderValues[PlaceHolder] + if type(Value) in self._LIST_TYPES: + if RepeatTime < 0: + RepeatTime = len(Value) + elif RepeatTime != len(Value): + EdkLogger.error( + "TemplateString", + PARAMETER_INVALID, + "${%s} has different repeat time from others!" % PlaceHolder, + ExtraData=str(self._Template) + ) + RepeatPlaceHolders["${%s}" % PlaceHolder] = Value + else: + NonRepeatPlaceHolders["${%s}" % PlaceHolder] = Value + + if NonRepeatPlaceHolders: + StringList = [] + for S in self._SubSectionList: + if S not in NonRepeatPlaceHolders: + StringList.append(S) + else: + StringList.append(str(NonRepeatPlaceHolders[S])) + else: + StringList = self._SubSectionList + + if RepeatPlaceHolders: + TempStringList = [] + for Index in range(RepeatTime): + for S in StringList: + if S not in RepeatPlaceHolders: + TempStringList.append(S) + else: + TempStringList.append(str(RepeatPlaceHolders[S][Index])) + StringList = TempStringList + + return "".join(StringList) + + ## Constructor + def __init__(self, Template=None): + self.String = '' + self._Template = Template + self._TemplateSectionList = self._Parse(Template) + + ## str() operator + # + # @retval string The string replaced + # + def __str__(self): + return self.String + + ## Split the template string into fragments per the ${BEGIN} and ${END} flags + # + # @retval list A list of TemplateString.Section objects + # + def _Parse(self, Template): + SectionStart = 0 + SearchFrom = 0 + MatchEnd = 0 + PlaceHolderList = [] + TemplateSectionList = [] + while Template: + MatchObj = gPlaceholderPattern.search(Template, SearchFrom) + if not MatchObj: + if MatchEnd < len(Template): + TemplateSection = TemplateString.Section(Template[SectionStart:], PlaceHolderList) + TemplateSectionList.append(TemplateSection) + break + + MatchString = MatchObj.group(1) + MatchStart = MatchObj.start() + MatchEnd = MatchObj.end() + + if MatchString == self._REPEAT_START_FLAG: + if MatchStart > SectionStart: + TemplateSection = TemplateString.Section(Template[SectionStart:MatchStart], PlaceHolderList) + TemplateSectionList.append(TemplateSection) + SectionStart = MatchEnd + PlaceHolderList = [] + elif MatchString == self._REPEAT_END_FLAG: + TemplateSection = TemplateString.Section(Template[SectionStart:MatchStart], PlaceHolderList) + TemplateSectionList.append(TemplateSection) + SectionStart = MatchEnd + PlaceHolderList = [] + else: + PlaceHolderList.append((MatchString, MatchStart - SectionStart, MatchEnd - SectionStart)) + SearchFrom = MatchEnd + return TemplateSectionList + + ## Replace the string template with dictionary of placeholders and append it to previous one + # + # @param AppendString The string template to append + # @param Dictionary The placeholder dictionaries + # + def Append(self, AppendString, Dictionary=None): + if Dictionary: + SectionList = self._Parse(AppendString) + self.String += "".join([S.Instantiate(Dictionary) for S in SectionList]) + else: + self.String += AppendString + + ## Replace the string template with dictionary of placeholders + # + # @param Dictionary The placeholder dictionaries + # + # @retval str The string replaced with placeholder values + # + def Replace(self, Dictionary=None): + return "".join([S.Instantiate(Dictionary) for S in self._TemplateSectionList]) + +## Progress indicator class +# +# This class makes use of thread to print progress on console. +# +class Progressor: + # for avoiding deadloop + _StopFlag = None + _ProgressThread = None + _CheckInterval = 0.25 + + ## Constructor + # + # @param OpenMessage The string printed before progress charaters + # @param CloseMessage The string printed after progress charaters + # @param ProgressChar The charater used to indicate the progress + # @param Interval The interval in seconds between two progress charaters + # + def __init__(self, OpenMessage="", CloseMessage="", ProgressChar='.', Interval=1.0): + self.PromptMessage = OpenMessage + self.CodaMessage = CloseMessage + self.ProgressChar = ProgressChar + self.Interval = Interval + if Progressor._StopFlag == None: + Progressor._StopFlag = threading.Event() + + ## Start to print progress charater + # + # @param OpenMessage The string printed before progress charaters + # + def Start(self, OpenMessage=None): + if OpenMessage != None: + self.PromptMessage = OpenMessage + Progressor._StopFlag.clear() + if Progressor._ProgressThread == None: + Progressor._ProgressThread = threading.Thread(target=self._ProgressThreadEntry) + Progressor._ProgressThread.setDaemon(False) + Progressor._ProgressThread.start() + + ## Stop printing progress charater + # + # @param CloseMessage The string printed after progress charaters + # + def Stop(self, CloseMessage=None): + OriginalCodaMessage = self.CodaMessage + if CloseMessage != None: + self.CodaMessage = CloseMessage + self.Abort() + self.CodaMessage = OriginalCodaMessage + + ## Thread entry method + def _ProgressThreadEntry(self): + sys.stdout.write(self.PromptMessage + " ") + sys.stdout.flush() + TimeUp = 0.0 + while not Progressor._StopFlag.isSet(): + if TimeUp <= 0.0: + sys.stdout.write(self.ProgressChar) + sys.stdout.flush() + TimeUp = self.Interval + time.sleep(self._CheckInterval) + TimeUp -= self._CheckInterval + sys.stdout.write(" " + self.CodaMessage + "\n") + sys.stdout.flush() + + ## Abort the progress display + @staticmethod + def Abort(): + if Progressor._StopFlag != None: + Progressor._StopFlag.set() + if Progressor._ProgressThread != None: + Progressor._ProgressThread.join() + Progressor._ProgressThread = 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, sdict): + for key in sdict: + if key not in self._key_list: + self._key_list.append(key) + IterableUserDict.__setitem__(self, key, sdict[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 = kv[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 + + def update(self, dict=None, **kwargs): + if dict != None: + for k, v in dict.items(): + self[k] = v + if len(kwargs): + for k, v in kwargs.items(): + self[k] = v + +## Dictionary with restricted keys +# +class rdict(dict): + ## Constructor + def __init__(self, KeyList): + for Key in KeyList: + dict.__setitem__(self, Key, "") + + ## []= operator + def __setitem__(self, key, value): + if key not in self: + EdkLogger.error("RestrictedDict", ATTRIBUTE_SET_FAILURE, "Key [%s] is not allowed" % key, + ExtraData=", ".join(dict.keys(self))) + dict.__setitem__(self, key, value) + + ## =[] operator + def __getitem__(self, key): + if key not in self: + return "" + return dict.__getitem__(self, key) + + ## del operator + def __delitem__(self, key): + EdkLogger.error("RestrictedDict", ATTRIBUTE_ACCESS_DENIED, ExtraData="del") + + ## Empty the dict + def clear(self): + for Key in self: + self.__setitem__(Key, "") + + ## Return value related to a key, and remove the (key, value) from the dict + def pop(self, key, *dv): + EdkLogger.error("RestrictedDict", ATTRIBUTE_ACCESS_DENIED, ExtraData="pop") + + ## Return (key, value) pair, and remove the (key, value) from the dict + def popitem(self): + EdkLogger.error("RestrictedDict", ATTRIBUTE_ACCESS_DENIED, ExtraData="popitem") + +## Dictionary using prioritized list as key +# +class tdict: + _ListType = type([]) + _TupleType = type(()) + _Wildcard = 'COMMON' + _ValidWildcardList = ['COMMON', 'DEFAULT', 'ALL', '*', 'PLATFORM'] + + def __init__(self, _Single_=False, _Level_=2): + self._Level_ = _Level_ + self.data = {} + self._Single_ = _Single_ + + # =[] operator + def __getitem__(self, key): + KeyType = type(key) + RestKeys = None + if KeyType == self._ListType or KeyType == self._TupleType: + FirstKey = key[0] + if len(key) > 1: + RestKeys = key[1:] + elif self._Level_ > 1: + RestKeys = [self._Wildcard for i in range(0, self._Level_-1)] + else: + FirstKey = key + if self._Level_ > 1: + RestKeys = [self._Wildcard for i in range(0, self._Level_-1)] + + if FirstKey == None or str(FirstKey).upper() in self._ValidWildcardList: + FirstKey = self._Wildcard + + if self._Single_: + return self._GetSingleValue(FirstKey, RestKeys) + else: + return self._GetAllValues(FirstKey, RestKeys) + + def _GetSingleValue(self, FirstKey, RestKeys): + Value = None + #print "%s-%s" % (FirstKey, self._Level_) , + if self._Level_ > 1: + if FirstKey == self._Wildcard: + if FirstKey in self.data: + Value = self.data[FirstKey][RestKeys] + if Value == None: + for Key in self.data: + Value = self.data[Key][RestKeys] + if Value != None: break + else: + if FirstKey in self.data: + Value = self.data[FirstKey][RestKeys] + if Value == None and self._Wildcard in self.data: + #print "Value=None" + Value = self.data[self._Wildcard][RestKeys] + else: + if FirstKey == self._Wildcard: + if FirstKey in self.data: + Value = self.data[FirstKey] + if Value == None: + for Key in self.data: + Value = self.data[Key] + if Value != None: break + else: + if FirstKey in self.data: + Value = self.data[FirstKey] + elif self._Wildcard in self.data: + Value = self.data[self._Wildcard] + return Value + + def _GetAllValues(self, FirstKey, RestKeys): + Value = [] + if self._Level_ > 1: + if FirstKey == self._Wildcard: + for Key in self.data: + Value += self.data[Key][RestKeys] + else: + if FirstKey in self.data: + Value += self.data[FirstKey][RestKeys] + if self._Wildcard in self.data: + Value += self.data[self._Wildcard][RestKeys] + else: + if FirstKey == self._Wildcard: + for Key in self.data: + Value.append(self.data[Key]) + else: + if FirstKey in self.data: + Value.append(self.data[FirstKey]) + if self._Wildcard in self.data: + Value.append(self.data[self._Wildcard]) + return Value + + ## []= operator + def __setitem__(self, key, value): + KeyType = type(key) + RestKeys = None + if KeyType == self._ListType or KeyType == self._TupleType: + FirstKey = key[0] + if len(key) > 1: + RestKeys = key[1:] + else: + RestKeys = [self._Wildcard for i in range(0, self._Level_-1)] + else: + FirstKey = key + if self._Level_ > 1: + RestKeys = [self._Wildcard for i in range(0, self._Level_-1)] + + if FirstKey in self._ValidWildcardList: + FirstKey = self._Wildcard + + if FirstKey not in self.data and self._Level_ > 0: + self.data[FirstKey] = tdict(self._Single_, self._Level_ - 1) + + if self._Level_ > 1: + self.data[FirstKey][RestKeys] = value + else: + self.data[FirstKey] = value + + def SetGreedyMode(self): + self._Single_ = False + if self._Level_ > 1: + for Key in self.data: + self.data[Key].SetGreedyMode() + + def SetSingleMode(self): + self._Single_ = True + if self._Level_ > 1: + for Key in self.data: + self.data[Key].SetSingleMode() + +## Boolean chain list +# +class Blist(UserList): + def __init__(self, initlist=None): + UserList.__init__(self, initlist) + def __setitem__(self, i, item): + if item not in [True, False]: + if item == 0: + item = False + else: + item = True + self.data[i] = item + def _GetResult(self): + Value = True + for item in self.data: + Value &= item + return Value + Result = property(_GetResult) + +def ParseConsoleLog(Filename): + Opr = open(os.path.normpath(Filename), 'r') + Opw = open(os.path.normpath(Filename + '.New'), 'w+') + for Line in Opr.readlines(): + if Line.find('.efi') > -1: + Line = Line[Line.rfind(' ') : Line.rfind('.efi')].strip() + Opw.write('%s\n' % Line) + + Opr.close() + Opw.close() + +## check format of PCD value against its the datum type +# +# For PCD value setting +# +def CheckPcdDatum(Type, Value): + if Type == "VOID*": + if not ((Value.startswith('L"') or Value.startswith('"') and Value.endswith('"')) + or (Value.startswith('{') and Value.endswith('}')) + ): + return False, "Invalid value [%s] of type [%s]; must be in the form of {...} for array"\ + ", or \"...\" for string, or L\"...\" for unicode string" % (Value, Type) + elif Type == 'BOOLEAN': + if Value not in ['TRUE', 'FALSE']: + return False, "Invalid value [%s] of type [%s]; must be TRUE or FALSE" % (Value, Type) + elif type(Value) == type(""): + try: + Value = long(Value, 0) + except: + return False, "Invalid value [%s] of type [%s];"\ + " must be a hexadecimal, decimal or octal in C language format."\ + % (Value, Type) + + return True, "" + +## Split command line option string to list +# +# subprocess.Popen needs the args to be a sequence. Otherwise there's problem +# in non-windows platform to launch command +# +def SplitOption(OptionString): + OptionList = [] + LastChar = " " + OptionStart = 0 + QuotationMark = "" + for Index in range(0, len(OptionString)): + CurrentChar = OptionString[Index] + if CurrentChar in ['"', "'"]: + if QuotationMark == CurrentChar: + QuotationMark = "" + elif QuotationMark == "": + QuotationMark = CurrentChar + continue + elif QuotationMark: + continue + + if CurrentChar in ["/", "-"] and LastChar in [" ", "\t", "\r", "\n"]: + if Index > OptionStart: + OptionList.append(OptionString[OptionStart:Index-1]) + OptionStart = Index + LastChar = CurrentChar + OptionList.append(OptionString[OptionStart:]) + return OptionList + +def CommonPath(PathList): + P1 = min(PathList).split(os.path.sep) + P2 = max(PathList).split(os.path.sep) + for Index in xrange(min(len(P1), len(P2))): + if P1[Index] != P2[Index]: + return os.path.sep.join(P1[:Index]) + return os.path.sep.join(P1) + +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 + # + # @retval string Formatted String + # + def __str__(self): + return self.Path + + ## Override __eq__ function + # + # Check whether PathClass are the same + # + # @retval False The two PathClass are different + # @retval True The two 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 + # + # @retval string Key for hash table + # + def __hash__(self): + return hash(self.Path) + + def _GetFileKey(self): + if self._Key == None: + self._Key = self.Path.upper() # + self.ToolChainFamily + self.TagName + self.ToolCode + self.Target + return self._Key + + def Validate(self, Type='', CaseSensitive=True): + if GlobalData.gCaseInsensitive: + CaseSensitive = False + if Type and Type.lower() != self.Type: + return 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: + return FILE_NOT_FOUND, self.File + + 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 = 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) + +## +# +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +# +if __name__ == '__main__': + pass + diff --git a/BaseTools/Source/Python/Common/Parsing.py b/BaseTools/Source/Python/Common/Parsing.py new file mode 100644 index 0000000000..755f7901b5 --- /dev/null +++ b/BaseTools/Source/Python/Common/Parsing.py @@ -0,0 +1,935 @@ +## @file +# This file is used to define common parsing related functions used in parsing INF/DEC/DSC process +# +# Copyright (c) 2008, 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 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 +# +from String import * +from CommonDataClass.DataClass import * +from DataType import * + +## ParseContent +# +# Parse content of a DSC/INF/DEC file +# +def ParseContent(Lines, ): + for Line in Lines: + LineNo = LineNo + 1 + # + # Remove comments at tail and remove spaces again + # + Line = CleanString(Line) + if Line == '': + continue + + # + # Find a new section tab + # First insert previous section items + # And then parse the content of the new section + # + if Line.startswith(TAB_SECTION_START) and Line.endswith(TAB_SECTION_END): + # + # Insert items data of previous section + # + self.InsertSectionItemsIntoDatabase(FileID, Filename, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList) + # + # Parse the new section + # + SectionItemList = [] + ArchList = [] + ThirdList = [] + + LineList = GetSplitValueList(Line[len(TAB_SECTION_START):len(Line) - len(TAB_SECTION_END)], TAB_COMMA_SPLIT) + for Item in LineList: + ItemList = GetSplitValueList(Item, TAB_SPLIT) + CurrentSection = ItemList[0] + if CurrentSection.upper() not in self.KeyList: + RaiseParserError(Line, CurrentSection, Filename, '', LineNo) + ItemList.append('') + ItemList.append('') + if len(ItemList) > 5: + RaiseParserError(Line, CurrentSection, Filename, '', LineNo) + else: + if ItemList[1] != '' and ItemList[1].upper() not in ARCH_LIST_FULL: + EdkLogger.error("Parser", PARSER_ERROR, "Invalid Arch definition '%s' found" % ItemList[1], File=Filename, Line=LineNo) + ArchList.append(ItemList[1].upper()) + ThirdList.append(ItemList[2]) + + continue + + # + # Not in any defined section + # + if CurrentSection == TAB_UNKNOWN: + ErrorMsg = "%s is not in any defined section" % Line + EdkLogger.error("Parser", PARSER_ERROR, ErrorMsg, File=Filename, Line=LineNo) + + # + # Add a section item + # + SectionItemList.append([Line, LineNo]) + # End of parse + #End of For + + +## ParseDefineMacro +# +# Search whole table to find all defined Macro and replaced them with the real values +# +def ParseDefineMacro2(Table, RecordSets, GlobalMacro): + Macros = {} + # + # Find all DEFINE macros in section [Header] and its section + # + SqlCommand = """select Value1, Value2, BelongsToItem, StartLine, Arch from %s + where Model = %s + and Enabled > -1""" % (Table.Table, MODEL_META_DATA_DEFINE) + RecordSet = Table.Exec(SqlCommand) + for Record in RecordSet: + Macros[Record[0]] = Record[1] + + # + # Overrided by Global Macros + # + for Key in GlobalMacro.keys(): + Macros[Key] = GlobalMacro[Key] + + # + # Replace the Macros + # + for Key in RecordSets.keys(): + if RecordSets[Key] != []: + for Item in RecordSets[Key]: + Item[0] = ReplaceMacro(Item[0], Macros) + +## ParseDefineMacro +# +# Search whole table to find all defined Macro and replaced them with the real values +# +def ParseDefineMacro(Table, GlobalMacro): + Macros = {} + # + # Find all DEFINE macros + # + SqlCommand = """select Value1, Value2, BelongsToItem, StartLine, Arch from %s + where Model = %s + and Enabled > -1""" % (Table.Table, MODEL_META_DATA_DEFINE) + RecordSet = Table.Exec(SqlCommand) + for Record in RecordSet: +#*************************************************************************************************************************************************** +# The follow SqlCommand (expr replace) is not supported in Sqlite 3.3.4 which is used in Python 2.5 * +# Reserved Only * +# SqlCommand = """update %s set Value1 = replace(Value1, '%s', '%s') * +# where ID in (select ID from %s * +# where Model = %s * +# and Value1 like '%%%s%%' * +# and StartLine > %s * +# and Enabled > -1 * +# and Arch = '%s')""" % \ * +# (self.TblDsc.Table, Record[0], Record[1], self.TblDsc.Table, Record[2], Record[1], Record[3], Record[4]) * +#*************************************************************************************************************************************************** + Macros[Record[0]] = Record[1] + + # + # Overrided by Global Macros + # + for Key in GlobalMacro.keys(): + Macros[Key] = GlobalMacro[Key] + + # + # Found all defined macro and replaced + # + SqlCommand = """select ID, Value1 from %s + where Model != %s + and Value1 like '%%$(%%' and Value1 like '%%)%%' + and Enabled > -1""" % (Table.Table, MODEL_META_DATA_DEFINE) + FoundRecords = Table.Exec(SqlCommand) + for FoundRecord in FoundRecords: + NewValue = ReplaceMacro(FoundRecord[1], Macros) + SqlCommand = """update %s set Value1 = '%s' + where ID = %s""" % (Table.Table, ConvertToSqlString2(NewValue), FoundRecord[0]) + Table.Exec(SqlCommand) + +##QueryDefinesItem +# +# Search item of section [Defines] by name, return its values +# +# @param Table: The Table to be executed +# @param Name: The Name of item of section [Defines] +# @param Arch: The Arch of item of section [Defines] +# +# @retval RecordSet: A list of all matched records +# +def QueryDefinesItem(Table, Name, Arch, BelongsToFile): + SqlCommand = """select Value2 from %s + where Model = %s + and Value1 = '%s' + and Arch = '%s' + and BelongsToFile = %s + and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(Name), ConvertToSqlString2(Arch), BelongsToFile) + RecordSet = Table.Exec(SqlCommand) + if len(RecordSet) < 1: + SqlCommand = """select Value2 from %s + where Model = %s + and Value1 = '%s' + and Arch = '%s' + and BelongsToFile = %s + and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(Name), ConvertToSqlString2(TAB_ARCH_COMMON.upper()), BelongsToFile) + RecordSet = Table.Exec(SqlCommand) + if len(RecordSet) == 1: + if Name == TAB_INF_DEFINES_LIBRARY_CLASS: + return [RecordSet[0][0]] + else: + return GetSplitValueList(RecordSet[0][0]) + elif len(RecordSet) < 1: + return [''] + elif len(RecordSet) > 1: + RetVal = [] + for Record in RecordSet: + if Name == TAB_INF_DEFINES_LIBRARY_CLASS: + RetVal.append(Record[0]) + else: + Items = GetSplitValueList(Record[0]) + for Item in Items: + RetVal.append(Item) + return RetVal + +##QueryDefinesItem +# +# Search item of section [Defines] by name, return its values +# +# @param Table: The Table to be executed +# @param Name: The Name of item of section [Defines] +# @param Arch: The Arch of item of section [Defines] +# +# @retval RecordSet: A list of all matched records +# +def QueryDefinesItem2(Table, Arch, BelongsToFile): + SqlCommand = """select Value1, Value2, StartLine from %s + where Model = %s + and Arch = '%s' + and BelongsToFile = %s + and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(Arch), BelongsToFile) + RecordSet = Table.Exec(SqlCommand) + if len(RecordSet) < 1: + SqlCommand = """select Value1, Value2, StartLine from %s + where Model = %s + and Arch = '%s' + and BelongsToFile = %s + and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(TAB_ARCH_COMMON), BelongsToFile) + RecordSet = Table.Exec(SqlCommand) + + return RecordSet + +##QueryDscItem +# +# Search all dsc item for a specific section +# +# @param Table: The Table to be executed +# @param Model: The type of section +# +# @retval RecordSet: A list of all matched records +# +def QueryDscItem(Table, Model, BelongsToItem, BelongsToFile): + SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s + where Model = %s + and BelongsToItem = %s + and BelongsToFile = %s + and Enabled > -1""" % (Table.Table, Model, BelongsToItem, BelongsToFile) + return Table.Exec(SqlCommand) + +##QueryDecItem +# +# Search all dec item for a specific section +# +# @param Table: The Table to be executed +# @param Model: The type of section +# +# @retval RecordSet: A list of all matched records +# +def QueryDecItem(Table, Model, BelongsToItem): + SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s + where Model = %s + and BelongsToItem = %s + and Enabled > -1""" % (Table.Table, Model, BelongsToItem) + return Table.Exec(SqlCommand) + +##QueryInfItem +# +# Search all dec item for a specific section +# +# @param Table: The Table to be executed +# @param Model: The type of section +# +# @retval RecordSet: A list of all matched records +# +def QueryInfItem(Table, Model, BelongsToItem): + SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s + where Model = %s + and BelongsToItem = %s + and Enabled > -1""" % (Table.Table, Model, BelongsToItem) + return Table.Exec(SqlCommand) + +## GetBuildOption +# +# Parse a string with format "[:]=Flag" +# Return (Family, ToolFlag, Flag) +# +# @param String: String with BuildOption statement +# @param File: The file which defines build option, used in error report +# +# @retval truple() A truple structure as (Family, ToolChain, Flag) +# +def GetBuildOption(String, File, LineNo = -1): + if String.find(TAB_EQUAL_SPLIT) < 0: + RaiseParserError(String, 'BuildOptions', File, '[:]=Flag', LineNo) + (Family, ToolChain, Flag) = ('', '', '') + List = GetSplitValueList(String, 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 | +# +# @param Item: String as | +# @param ContainerFile: The file which describes the library class, used for error report +# +# @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item +# +def GetLibraryClass(Item, ContainerFile, WorkspaceDir, LineNo = -1): + List = GetSplitValueList(Item[0]) + SupMod = SUP_MODULE_LIST_STRING + if len(List) != 2: + RaiseParserError(Item[0], 'LibraryClasses', ContainerFile, '|') + 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 [|][|.] +# +# @param Item: String as | +# @param ContainerFile: The file which describes the library class, used for error report +# +# @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item +# +def GetLibraryClassOfInf(Item, ContainerFile, WorkspaceDir, LineNo = -1): + ItemList = GetSplitValueList((Item[0] + DataType.TAB_VALUE_SPLIT * 2)) + SupMod = SUP_MODULE_LIST_STRING + + if len(ItemList) > 5: + RaiseParserError(Item[0], 'LibraryClasses', ContainerFile, '[|][|.]') + 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 . +# +# @param TokenInfoString: String to be checked +# @param Section: Used for error report +# @param File: Used for error report +# +# @retval True PcdTokenInfo is in correct format +# +def CheckPcdTokenInfo(TokenInfoString, Section, File, LineNo = -1): + Format = '.' + if TokenInfoString != '' and TokenInfoString != None: + TokenInfoList = GetSplitValueList(TokenInfoString, TAB_SPLIT) + if len(TokenInfoList) == 2: + return True + + RaiseParserError(TokenInfoString, Section, File, Format, LineNo) + +## Get Pcd +# +# Get Pcd of Dsc as .|[||] +# +# @param Item: String as .|[||] +# @param ContainerFile: The file which describes the pcd, used for error report +# +# @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type) +# +def GetPcd(Item, Type, ContainerFile, LineNo = -1): + TokenGuid, TokenName, Value, MaximumDatumSize, Token = '', '', '', '', '' + List = GetSplitValueList(Item + TAB_VALUE_SPLIT * 2) + + if len(List) < 4 or len(List) > 6: + RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '.|[||]', LineNo) + else: + Value = List[1] + MaximumDatumSize = List[2] + Token = List[3] + + if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo): + (TokenGuid, TokenName) = GetSplitValueList(List[0], TAB_SPLIT) + + return (TokenName, TokenGuid, Value, MaximumDatumSize, Token, Type) + +## Get FeatureFlagPcd +# +# Get FeatureFlagPcd of Dsc as .|TRUE/FALSE +# +# @param Item: String as .|TRUE/FALSE +# @param ContainerFile: The file which describes the pcd, used for error report +# +# @retval (TokenInfo[1], TokenInfo[0], List[1], Type) +# +def GetFeatureFlagPcd(Item, Type, ContainerFile, LineNo = -1): + TokenGuid, TokenName, Value = '', '', '' + List = GetSplitValueList(Item) + if len(List) != 2: + RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '.|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 .|[|[|]] +# +# @param Item: String as .|TRUE/FALSE +# @param ContainerFile: The file which describes the pcd, used for error report +# +# @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type) +# +def GetDynamicDefaultPcd(Item, Type, ContainerFile, LineNo = -1): + TokenGuid, TokenName, Value, DatumTyp, MaxDatumSize = '', '', '', '', '' + List = GetSplitValueList(Item + TAB_VALUE_SPLIT * 2) + if len(List) < 4 or len(List) > 8: + RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '.|[|[|]]', LineNo) + else: + Value = List[1] + DatumTyp = List[2] + MaxDatumSize = List[3] + if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo): + (TokenGuid, TokenName) = GetSplitValueList(List[0], TAB_SPLIT) + + return (TokenName, TokenGuid, Value, DatumTyp, MaxDatumSize, Type) + +## Get DynamicHiiPcd +# +# Get DynamicHiiPcd of Dsc as .|||[|[|]] +# +# @param Item: String as .|TRUE/FALSE +# @param ContainerFile: The file which describes the pcd, used for error report +# +# @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], List[4], List[5], Type) +# +def GetDynamicHiiPcd(Item, Type, ContainerFile, LineNo = -1): + TokenGuid, TokenName, L1, L2, L3, L4, L5 = '', '', '', '', '', '', '' + List = GetSplitValueList(Item + TAB_VALUE_SPLIT * 2) + if len(List) < 6 or len(List) > 8: + RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '.|||[|[|]]', LineNo) + else: + L1, L2, L3, L4, L5 = 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, L1, L2, L3, L4, L5, Type) + +## Get DynamicVpdPcd +# +# Get DynamicVpdPcd of Dsc as .|[|] +# +# @param Item: String as .|TRUE/FALSE +# @param ContainerFile: The file which describes the pcd, used for error report +# +# @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], Type) +# +def GetDynamicVpdPcd(Item, Type, ContainerFile, LineNo = -1): + TokenGuid, TokenName, L1, L2 = '', '', '', '' + List = GetSplitValueList(Item + TAB_VALUE_SPLIT) + if len(List) < 3 or len(List) > 4: + RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '.|[|]', LineNo) + else: + L1, L2 = List[1], List[2] + if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo): + (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT) + + return (TokenName, TokenGuid, L1, L2, 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 +# +# @retval True Get component successfully +# +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(TAB_INCLUDE.upper() + ' ') > -1 or Line.upper().find(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('') != -1: + (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (True, False, False, False, False, False, False) + continue + if Line.find('') != -1: + (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, True, False, False, False, False, False) + continue + if Line.find('') != -1: + (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, True, False, False, False, False) + continue + if Line.find('') != -1: + (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, True, False, False, False) + continue + if Line.find('') != -1: + (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, True, False, False) + continue + if Line.find('') != -1: + (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, True, False) + continue + if Line.find('') != -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 +# +# @retval truple() A pair as (InfFilename, ExecFilename) +# +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, Key, 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('') != -1: + (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (True, False, False, False, False, False, False) + continue + if Line.find('') != -1: + (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, True, False, False, False, False, False) + continue + if Line.find('') != -1: + (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, True, False, False, False, False) + continue + if Line.find('') != -1: + (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, True, False, False, False) + continue + if Line.find('') != -1: + (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, True, False, False) + continue + if Line.find('') != -1: + (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, True, False) + continue + if Line.find('') != -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 [|[|[|[|]]]] +# +# @param Item: String as [|[|[|[|]]]] +# @param ContainerFile: The file which describes the library class, used for error report +# +# @retval (List[0], List[1], List[2], List[3], List[4]) +# +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, '[|[|[|[|]]]]', 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 [|[|[|[|]]]] +# +# @param Item: String as [|[|[|[|]]]] +# @param ContainerFile: The file which describes the library class, used for error report +# +# @retval (List[0], List[1], List[2], List[3]) +# +def GetBinary(Item, ContainerFile, FileRelativePath, LineNo = -1): + ItemNew = Item + DataType.TAB_VALUE_SPLIT + List = GetSplitValueList(ItemNew) + if len(List) != 4 and len(List) != 5: + RaiseParserError(Item, 'Binaries', ContainerFile, "||[|.]", LineNo) + else: + if List[3] != '': + CheckPcdTokenInfo(List[3], 'Binaries', ContainerFile, LineNo) + + return (List[0], List[1], List[2], List[3]) + +## Get Guids/Protocols/Ppis +# +# Get Guids/Protocols/Ppis of Inf as [|] +# +# @param Item: String as [|] +# @param Type: Type of parsing string +# @param ContainerFile: The file which describes the library class, used for error report +# +# @retval (List[0], List[1]) +# +def GetGuidsProtocolsPpisOfInf(Item, Type, ContainerFile, LineNo = -1): + ItemNew = Item + TAB_VALUE_SPLIT + List = GetSplitValueList(ItemNew) + if List[1] != '': + CheckPcdTokenInfo(List[1], Type, ContainerFile, LineNo) + + return (List[0], List[1]) + +## Get Guids/Protocols/Ppis +# +# Get Guids/Protocols/Ppis of Dec as = +# +# @param Item: String as = +# @param Type: Type of parsing string +# @param ContainerFile: The file which describes the library class, used for error report +# +# @retval (List[0], List[1]) +# +def GetGuidsProtocolsPpisOfDec(Item, Type, ContainerFile, LineNo = -1): + List = GetSplitValueList(Item, DataType.TAB_EQUAL_SPLIT) + if len(List) != 2: + RaiseParserError(Item, Type, ContainerFile, '=', LineNo) + + return (List[0], List[1]) + +## GetPackage +# +# Get Package of Inf as [|] +# +# @param Item: String as [|] +# @param Type: Type of parsing string +# @param ContainerFile: The file which describes the library class, used for error report +# +# @retval (List[0], List[1]) +# +def GetPackage(Item, ContainerFile, FileRelativePath, LineNo = -1): + ItemNew = Item + 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 .[|] +# +# @param Item: The string describes pcd +# @param Type: The type of Pcd +# @param File: The file which describes the pcd, used for error report +# +# @retval (TokenSpcCName, TokenCName, Value, ItemType) Formatted Pcd Item +# +def GetPcdOfInf(Item, Type, File, LineNo): + Format = '.[|]' + TokenGuid, TokenName, Value, InfType = '', '', '', '' + + if Type == TAB_PCDS_FIXED_AT_BUILD: + InfType = TAB_INF_FIXED_PCD + elif Type == TAB_PCDS_PATCHABLE_IN_MODULE: + InfType = TAB_INF_PATCH_PCD + elif Type == TAB_PCDS_FEATURE_FLAG: + InfType = TAB_INF_FEATURE_PCD + elif Type == TAB_PCDS_DYNAMIC_EX: + InfType = TAB_INF_PCD_EX + elif Type == TAB_PCDS_DYNAMIC: + InfType = TAB_INF_PCD + List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT) + if len(List) < 2 or len(List) > 3: + RaiseParserError(Item, InfType, File, Format, LineNo) + else: + Value = List[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] + + return (TokenGuid, TokenName, Value, Type) + + +## Get Pcd Values of Dec +# +# Get Pcd of Dec as .||| +# @retval (TokenSpcCName, TokenCName, Value, DatumType, Token, ItemType) Formatted Pcd Item +# +def GetPcdOfDec(Item, Type, File, LineNo = -1): + Format = '.|||' + 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 +# +# 1. Insert a record into TblDec +# Value1: Macro Name +# Value2: Macro Value +# +def ParseDefine(LineValue, StartLine, Table, FileID, Filename, SectionName, SectionModel, Arch): + EdkLogger.debug(EdkLogger.DEBUG_2, "DEFINE statement '%s' found in section %s" % (LineValue, SectionName)) + Define = GetSplitValueList(CleanString(LineValue[LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') + len(DataType.TAB_DEFINE + ' ') : ]), TAB_EQUAL_SPLIT, 1) + Table.Insert(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 +# +def InsertSectionItems(Model, CurrentSection, 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 = TAB_ARCH_COMMON + + Records = RecordSet[Model] + for SectionItem in SectionItemList: + BelongsToItem, EndLine, EndColumn = -1, -1, -1 + LineValue, StartLine, EndLine, Comment = SectionItem[0], SectionItem[1], SectionItem[1], SectionItem[2] + + EdkLogger.debug(4, "Parsing %s ..." %LineValue) + # And then parse DEFINE statement + if LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') > -1: + continue + + # At last parse other sections + ID = -1 + Records.append([LineValue, Arch, StartLine, ID, Third, Comment]) + + if RecordSet != {}: + RecordSet[Model] = Records + +## Insert records to database +# +# Insert item data of a section to database +# @param Table: The Table to be inserted +# @param FileID: The ID of belonging file +# @param Filename: The name of belonging file +# @param CurrentSection: The name of currect section +# @param SectionItemList: A list of items of the section +# @param ArchList: A list of arches +# @param ThirdList: A list of third parameters, ModuleType for LibraryClass and SkuId for Dynamic Pcds +# @param IfDefList: A list of all conditional statements +# @param RecordSet: A dict of all parsed records +# +def InsertSectionItemsIntoDatabase(Table, FileID, Filename, Model, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList, RecordSet): + # + # Insert each item data of a section + # + for Index in range(0, len(ArchList)): + Arch = ArchList[Index] + Third = ThirdList[Index] + if Arch == '': + Arch = TAB_ARCH_COMMON + + Records = RecordSet[Model] + for SectionItem in SectionItemList: + BelongsToItem, EndLine, EndColumn = -1, -1, -1 + LineValue, StartLine, EndLine = SectionItem[0], SectionItem[1], SectionItem[1] + + EdkLogger.debug(4, "Parsing %s ..." %LineValue) + # + # And then parse DEFINE statement + # + if LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') > -1: + ParseDefine(LineValue, StartLine, Table, FileID, Filename, CurrentSection, Model, Arch) + continue + + # + # At last parse other sections + # + ID = Table.Insert(Model, LineValue, Third, Third, '', '', Arch, -1, FileID, StartLine, -1, StartLine, -1, 0) + Records.append([LineValue, Arch, StartLine, ID, Third]) + + if RecordSet != {}: + RecordSet[Model] = Records + +## GenMetaDatSectionItem +def GenMetaDatSectionItem(Key, Value, List): + if Key not in List: + List[Key] = [Value] + else: + List[Key].append(Value) \ No newline at end of file diff --git a/BaseTools/Source/Python/Common/PyUtility.pyd b/BaseTools/Source/Python/Common/PyUtility.pyd new file mode 100644 index 0000000000..5bb57d91e0 Binary files /dev/null and b/BaseTools/Source/Python/Common/PyUtility.pyd differ diff --git a/BaseTools/Source/Python/Common/String.py b/BaseTools/Source/Python/Common/String.py new file mode 100644 index 0000000000..5da0cacfb0 --- /dev/null +++ b/BaseTools/Source/Python/Common/String.py @@ -0,0 +1,703 @@ +## @file +# This file is used to define common string related functions used in parsing process +# +# Copyright (c) 2007 ~ 2008, 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 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 re +import DataType +import os.path +import string +import EdkLogger as EdkLogger + +from GlobalData import * +from BuildToolError import * + +## 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 +# +# @retval list() A list for splitted string +# +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 = " +# 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 +# +# @retval 0 DEFINE statement found, and valid +# @retval 1 DEFINE statement found, but not valid +# @retval -1 DEFINE statement not found +# +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 + +## GenInclude +# +# Parse a string with format "!include " +# Return the file path +# Return False if invalid format or NOT FOUND +# +# @param String: String with INCLUDE statement +# @param IncludeFiles: INCLUDE statement to be parsed +# @param Arch: Supportted Arch +# +# @retval True +# @retval False +# +def GenInclude(String, IncludeFiles, Arch): + if String.upper().find(DataType.TAB_INCLUDE.upper() + ' ') > -1: + IncludeFile = CleanString(String[String.upper().find(DataType.TAB_INCLUDE.upper() + ' ') + len(DataType.TAB_INCLUDE + ' ') : ]) + MergeArches(IncludeFiles, IncludeFile, Arch) + return True + else: + return False + +## 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 +# +# @retval True Get library classes successfully +# +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 +# +# @retval True Get Dynamic Pcds successfully +# +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 +# +# @retval ReturnValue A list for module types +# +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 strings list +# +# This method replace macros used in a given string list. The macros are +# given in a dictionary. +# +# @param StringList StringList to be processed +# @param MacroDefinitions The macro definitions in the form of dictionary +# @param SelfReplacement To decide whether replace un-defined macro to '' +# +# @retval NewList A new string list whose macros are replaced +# +def ReplaceMacros(StringList, MacroDefinitions={}, SelfReplacement = False): + NewList = [] + for String in StringList: + if type(String) == type(''): + NewList.append(ReplaceMacro(String, MacroDefinitions, SelfReplacement)) + else: + NewList.append(String) + + return NewList + +## 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 '' +# +# @retval string The string whose macros are replaced +# +def ReplaceMacro(String, MacroDefinitions={}, SelfReplacement = False): + LastString = String + while MacroDefinitions: + MacroUsed = gMacroPattern.findall(String) + # 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, '') + continue + String = String.replace("$(%s)" % Macro, MacroDefinitions[Macro]) + # 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 +# +# @retval Path Formatted path +# +def NormPath(Path, Defines = {}): + IsRelativePath = False + 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 +# +# @retval Path Formatted path +# +def CleanString(Line, CommentCharacter = DataType.TAB_COMMENT_SPLIT, AllowCppStyleComment=False): + # + # remove whitespace + # + Line = Line.strip(); + # + # Replace R8's comment character + # + if AllowCppStyleComment: + Line = Line.replace(DataType.TAB_COMMENT_R8_SPLIT, CommentCharacter) + # + # remove comments + # + Line = Line.split(CommentCharacter, 1)[0]; + # + # remove whitespace again + # + Line = Line.strip(); + + return Line + +## 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 +# +# @retval True Successfully executed +# +def GetMultipleValuesOfKeyFromLines(Lines, Key, KeyValues, CommentCharacter): + 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 +# +# @retval string The defined value +# +def GetDefineValue(String, Key, CommentCharacter): + 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 +# +# @retval True Successfully executed +# +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(string.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): + 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: + EdkLogger.error("Parser", FORMAT_INVALID, Line=LineNo, File=FileName, RaiseError = EdkLogger.IsRaiseError) + + # + # Check [] + # + if Line.find('[') > -1 or Line.find(']') > -1: + # + # Only get one '[' or one ']' + # + if not (Line.find('[') > -1 and Line.find(']') > -1): + EdkLogger.error("Parser", FORMAT_INVALID, Line=LineNo, File=FileName, RaiseError = EdkLogger.IsRaiseError) + + # + # Regenerate FileContent + # + NewFileContent = NewFileContent + Line + '\r\n' + + if IsFailed: + EdkLogger.error("Parser", FORMAT_INVALID, Line=LineNo, File=FileName, RaiseError = EdkLogger.IsRaiseError) + + 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 +# +# @retval True The file type is correct +# +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(): + ContainerFile = open(ContainerFilename, 'r').read() + if LineNo == -1: + LineNo = GetLineNo(ContainerFile, Line) + ErrorMsg = "Invalid %s. '%s' is found, but '%s' file is needed" % (SectionName, CheckFilename, ExtName) + EdkLogger.error("Parser", PARSER_ERROR, ErrorMsg, Line=LineNo, + File=ContainerFilename, RaiseError = EdkLogger.IsRaiseError) + + 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 +# +# @retval The file full path if the file exists +# +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 = "Can't find file '%s' defined in section '%s'" % (CheckFile, SectionName) + EdkLogger.error("Parser", PARSER_ERROR, ErrorMsg, + File=ContainerFilename, Line = LineNo, RaiseError = EdkLogger.IsRaiseError) + + return CheckFile + +## GetLineNo +# +# Find the index of a line in a file +# +# @param FileContent: Search scope +# @param Line: Search key +# +# @retval int Index of the line +# @retval -1 The line is not found +# +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 = "Invalid statement '%s' is found in section '%s'" % (Line, Section) + if Format != '': + Format = "Correct format is " + Format + EdkLogger.error("Parser", PARSER_ERROR, ErrorMsg, File=File, Line=LineNo, ExtraData=Format, RaiseError = EdkLogger.IsRaiseError) + +## WorkspaceFile +# +# Return a full path with workspace dir +# +# @param WorkspaceDir: Workspace dir +# @param Filename: Relative file name +# +# @retval string A full path +# +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 +# +# @retval String: The string after removed '""' +# +def SplitString(String): + if String.startswith('\"'): + String = String[1:] + if String.endswith('\"'): + String = String[:-1] + + return String + +## Convert To Sql String +# +# 1. 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 +# +# 1. Replace "'" with "''" in the String +# +# @param String: A String to be converted +# +def ConvertToSqlString2(String): + return String.replace("'", "''") + +# +# Remove comment block +# +def RemoveBlockComment(Lines): + IsFindBlockComment = False + IsFindBlockCode = False + ReservedLine = '' + NewLines = [] + + for Line in Lines: + Line = Line.strip() + # + # Remove comment block + # + if Line.find(DataType.TAB_COMMENT_R8_START) > -1: + ReservedLine = GetSplitValueList(Line, DataType.TAB_COMMENT_R8_START, 1)[0] + IsFindBlockComment = True + if Line.find(DataType.TAB_COMMENT_R8_END) > -1: + Line = ReservedLine + GetSplitValueList(Line, DataType.TAB_COMMENT_R8_END, 1)[1] + ReservedLine = '' + IsFindBlockComment = False + if IsFindBlockComment: + NewLines.append('') + continue + + NewLines.append(Line) + return NewLines + +# +# Get String of a List +# +def GetStringOfList(List, Split = ' '): + if type(List) != type([]): + return List + Str = '' + for Item in List: + Str = Str + Item + Split + + return Str.strip() + +# +# Get HelpTextList from HelpTextClassList +# +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 + +def StringToArray(String): + if isinstance(String, unicode): + if len(unicode) ==0: + return "{0x00, 0x00}" + return "{%s, 0x00, 0x00}" % ", ".join(["0x%02x, 0x00" % ord(C) for C in String]) + elif String.startswith('L"'): + if String == "L\"\"": + return "{0x00, 0x00}" + else: + return "{%s, 0x00, 0x00}" % ", ".join(["0x%02x, 0x00" % ord(C) for C in String[2:-1]]) + elif String.startswith('"'): + if String == "\"\"": + return "{0x00}"; + else: + return "{%s, 0x00}" % ", ".join(["0x%02x" % ord(C) for C in String[1:-1]]) + else: + return '{%s, 0}' % ', '.join(String.split()) + +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 + +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) + +## +# +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +# +if __name__ == '__main__': + pass + diff --git a/BaseTools/Source/Python/Common/TargetTxtClassObject.py b/BaseTools/Source/Python/Common/TargetTxtClassObject.py new file mode 100644 index 0000000000..70178f54ce --- /dev/null +++ b/BaseTools/Source/Python/Common/TargetTxtClassObject.py @@ -0,0 +1,174 @@ +## @file +# This file is used to define each component of Target.txt file +# +# Copyright (c) 2007, 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 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 EdkLogger +import DataType +from BuildToolError import * +import GlobalData + +gDefaultTargetTxtFile = "Conf/target.txt" + +## TargetTxtClassObject +# +# This class defined content used in file target.txt +# +# @param object: Inherited from object class +# @param Filename: Input value for full path of target.txt +# +# @var TargetTxtDictionary: To store keys and values defined in target.txt +# +class TargetTxtClassObject(object): + def __init__(self, Filename = None): + self.TargetTxtDictionary = { + DataType.TAB_TAT_DEFINES_ACTIVE_PLATFORM : '', + DataType.TAB_TAT_DEFINES_ACTIVE_MODULE : '', + DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF : '', + DataType.TAB_TAT_DEFINES_MULTIPLE_THREAD : '', + DataType.TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER : '', + DataType.TAB_TAT_DEFINES_TARGET : [], + DataType.TAB_TAT_DEFINES_TOOL_CHAIN_TAG : [], + DataType.TAB_TAT_DEFINES_TARGET_ARCH : [], + DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF : '', + } + if Filename != None: + self.LoadTargetTxtFile(Filename) + + ## LoadTargetTxtFile + # + # Load target.txt file and parse it, return a set structure to store keys and values + # + # @param Filename: Input value for full path of target.txt + # + # @retval set() A set structure to store keys and values + # @retval 1 Error happenes in parsing + # + def LoadTargetTxtFile(self, Filename): + if os.path.exists(Filename) and os.path.isfile(Filename): + return self.ConvertTextFileToDict(Filename, '#', '=') + else: + EdkLogger.error("Target.txt Parser", FILE_NOT_FOUND, ExtraData=Filename) + return 1 + + ## ConvertTextFileToDict + # + # Convert a text file to a dictionary of (name:value) pairs. + # The data is saved to self.TargetTxtDictionary + # + # @param FileName: Text filename + # @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 + # + # @retval 0 Convert successfully + # @retval 1 Open file failed + # + def ConvertTextFileToDict(self, FileName, CommentCharacter, KeySplitCharacter): + F = None + try: + F = open(FileName,'r') + except: + EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=FileName) + if F != None: + F.close() + + for Line in F: + Line = Line.strip() + if Line.startswith(CommentCharacter) or Line == '': + continue + + LineList = Line.split(KeySplitCharacter, 1) + Key = LineList[0].strip() + if len(LineList) == 2: + Value = LineList[1].strip() + else: + Value = "" + + if Key in [DataType.TAB_TAT_DEFINES_ACTIVE_PLATFORM, DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF, \ + DataType.TAB_TAT_DEFINES_ACTIVE_MODULE, DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF]: + self.TargetTxtDictionary[Key] = Value.replace('\\', '/') + elif Key in [DataType.TAB_TAT_DEFINES_TARGET, DataType.TAB_TAT_DEFINES_TARGET_ARCH, \ + DataType.TAB_TAT_DEFINES_TOOL_CHAIN_TAG]: + self.TargetTxtDictionary[Key] = Value.split() + elif Key == DataType.TAB_TAT_DEFINES_MULTIPLE_THREAD: + if Value not in ["Enable", "Disable"]: + EdkLogger.error("build", FORMAT_INVALID, "Invalid setting of [%s]: %s." % (Key, Value), + ExtraData="\tSetting must be one of [Enable, Disable]", + File=FileName) + self.TargetTxtDictionary[Key] = Value + elif Key == DataType.TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER: + try: + V = int(Value, 0) + except: + EdkLogger.error("build", FORMAT_INVALID, "Invalid number of [%s]: %s." % (Key, Value), + File=FileName) + self.TargetTxtDictionary[Key] = Value + #elif Key not in GlobalData.gGlobalDefines: + # GlobalData.gGlobalDefines[Key] = Value + + F.close() + return 0 + + ## Print the dictionary + # + # Print all items of dictionary one by one + # + # @param Dict: The dictionary to be printed + # + def printDict(Dict): + if Dict != None: + KeyList = Dict.keys() + for Key in KeyList: + if Dict[Key] != '': + print Key + ' = ' + str(Dict[Key]) + + ## Print the dictionary + # + # Print the items of dictionary which matched with input key + # + # @param list: The dictionary to be printed + # @param key: The key of the item to be printed + # + def printList(Key, List): + if type(List) == type([]): + if len(List) > 0: + if Key.find(TAB_SPLIT) != -1: + print "\n" + Key + for Item in List: + print Item +## TargetTxtDict +# +# Load target.txt in input workspace dir +# +# @param WorkSpace: Workspace dir +# +# @retval Target An instance of TargetTxtClassObject() with loaded target.txt +# +def TargetTxtDict(WorkSpace): + Target = TargetTxtClassObject() + Target.LoadTargetTxtFile(os.path.normpath(os.path.join(WorkSpace, gDefaultTargetTxtFile))) + return Target + +## +# +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +# +if __name__ == '__main__': + pass + Target = TargetTxtDict(os.getenv("WORKSPACE")) + print Target.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER] + print Target.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TARGET] + print Target.TargetTxtDictionary diff --git a/BaseTools/Source/Python/Common/ToolDefClassObject.py b/BaseTools/Source/Python/Common/ToolDefClassObject.py new file mode 100644 index 0000000000..5a9a3096bb --- /dev/null +++ b/BaseTools/Source/Python/Common/ToolDefClassObject.py @@ -0,0 +1,217 @@ +## @file +# This file is used to define each component of tools_def.txt file +# +# Copyright (c) 2007, 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 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 re +import EdkLogger + +from Dictionary import * +from BuildToolError import * +from TargetTxtClassObject import * + +## +# Static vailabes used for pattern +# +gMacroRefPattern = re.compile('(DEF\([^\(\)]+\))') +gEnvRefPattern = re.compile('(ENV\([^\(\)]+\))') +gMacroDefPattern = re.compile("DEFINE\s+([^\s]+)") +gDefaultToolsDefFile = "Conf/tools_def.txt" + +## ToolDefClassObject +# +# This class defined content used in file tools_def.txt +# +# @param object: Inherited from object class +# @param Filename: Input value for full path of tools_def.txt +# +# @var ToolsDefTxtDictionary: To store keys and values defined in target.txt +# @var MacroDictionary: To store keys and values defined in DEFINE statement +# +class ToolDefClassObject(object): + def __init__(self, FileName = None): + self.ToolsDefTxtDictionary = {} + self.MacroDictionary = {} + for Env in os.environ: + self.MacroDictionary["ENV(%s)" % Env] = os.environ[Env] + + if FileName != None: + self.LoadToolDefFile(FileName) + + ## LoadToolDefFile + # + # Load target.txt file and parse it, return a set structure to store keys and values + # + # @param Filename: Input value for full path of tools_def.txt + # + def LoadToolDefFile(self, FileName): + FileContent = [] + if os.path.isfile(FileName): + try: + F = open(FileName,'r') + FileContent = F.readlines() + except: + EdkLogger.error("tools_def.txt parser", FILE_OPEN_FAILURE, ExtraData=FileName) + else: + EdkLogger.error("tools_def.txt parser", FILE_NOT_FOUND, ExtraData=FileName) + + self.ToolsDefTxtDatabase = { + TAB_TOD_DEFINES_TARGET : [], + TAB_TOD_DEFINES_TOOL_CHAIN_TAG : [], + TAB_TOD_DEFINES_TARGET_ARCH : [], + TAB_TOD_DEFINES_COMMAND_TYPE : [] + } + + for Index in range(len(FileContent)): + Line = FileContent[Index].strip() + if Line == "" or Line[0] == '#': + continue + NameValuePair = Line.split("=", 1) + if len(NameValuePair) != 2: + EdkLogger.warn("tools_def.txt parser", "Line %d: not correct assignment statement, skipped" % (Index + 1)) + continue + + Name = NameValuePair[0].strip() + Value = NameValuePair[1].strip() + + if Name == "IDENTIFIER": + EdkLogger.debug(EdkLogger.DEBUG_8, "Line %d: Found identifier statement, skipped: %s" % ((Index + 1), Value)) + continue + + MacroDefinition = gMacroDefPattern.findall(Name) + if MacroDefinition != []: + Done, Value = self.ExpandMacros(Value) + if not Done: + EdkLogger.error("tools_def.txt parser", ATTRIBUTE_NOT_AVAILABLE, + "Macro or Environment has not been defined", + ExtraData=Value[4:-1], File=FileName, Line=Index+1) + + MacroName = MacroDefinition[0].strip() + self.MacroDictionary["DEF(%s)" % MacroName] = Value + EdkLogger.debug(EdkLogger.DEBUG_8, "Line %d: Found macro: %s = %s" % ((Index + 1), MacroName, Value)) + continue + + Done, Value = self.ExpandMacros(Value) + if not Done: + EdkLogger.error("tools_def.txt parser", ATTRIBUTE_NOT_AVAILABLE, + "Macro or Environment has not been defined", + ExtraData=Value[4:-1], File=FileName, Line=Index+1) + + List = Name.split('_') + if len(List) != 5: + EdkLogger.verbose("Line %d: Not a valid name of definition: %s" % ((Index + 1), Name)) + continue + elif List[4] == '*': + EdkLogger.verbose("Line %d: '*' is not allowed in last field: %s" % ((Index + 1), Name)) + continue + else: + self.ToolsDefTxtDictionary[Name] = Value + if List[0] != '*': + self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET] += [List[0]] + if List[1] != '*': + self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG] += [List[1]] + if List[2] != '*': + self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH] += [List[2]] + if List[3] != '*': + self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE] += [List[3]] + if List[4] == TAB_TOD_DEFINES_FAMILY and List[2] == '*' and List[3] == '*': + if TAB_TOD_DEFINES_FAMILY not in self.ToolsDefTxtDatabase: + self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY] = {} + self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY][List[1]] = Value + self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY] = {} + self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY][List[1]] = Value + elif List[1] not in self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY]: + self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY][List[1]] = Value + self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY][List[1]] = Value + elif self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY][List[1]] != Value: + EdkLogger.verbose("Line %d: No override allowed for the family of a tool chain: %s" % ((Index + 1), Name)) + if List[4] == TAB_TOD_DEFINES_BUILDRULEFAMILY and List[2] == '*' and List[3] == '*': + if TAB_TOD_DEFINES_BUILDRULEFAMILY not in self.ToolsDefTxtDatabase \ + or List[1] not in self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY]: + EdkLogger.verbose("Line %d: The family is not specified, but BuildRuleFamily is specified for the tool chain: %s" % ((Index + 1), Name)) + self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY][List[1]] = Value + + self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET])) + self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG])) + self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH])) + self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE])) + + self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET].sort() + self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG].sort() + self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH].sort() + self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE].sort() + + KeyList = [TAB_TOD_DEFINES_TARGET, TAB_TOD_DEFINES_TOOL_CHAIN_TAG, TAB_TOD_DEFINES_TARGET_ARCH, TAB_TOD_DEFINES_COMMAND_TYPE] + for Index in range(3,-1,-1): + for Key in dict(self.ToolsDefTxtDictionary): + List = Key.split('_') + if List[Index] == '*': + for String in self.ToolsDefTxtDatabase[KeyList[Index]]: + List[Index] = String + NewKey = '%s_%s_%s_%s_%s' % tuple(List) + if NewKey not in self.ToolsDefTxtDictionary: + self.ToolsDefTxtDictionary[NewKey] = self.ToolsDefTxtDictionary[Key] + continue + del self.ToolsDefTxtDictionary[Key] + elif List[Index] not in self.ToolsDefTxtDatabase[KeyList[Index]]: + del self.ToolsDefTxtDictionary[Key] + + ## ExpandMacros + # + # Replace defined macros with real value + # + # @param Value: The string with unreplaced macros + # + # @retval Value: The string which has been replaced with real value + # + def ExpandMacros(self, Value): + EnvReference = gEnvRefPattern.findall(Value) + for Ref in EnvReference: + if Ref not in self.MacroDictionary: + return False, Ref + Value = Value.replace(Ref, self.MacroDictionary[Ref]) + + MacroReference = gMacroRefPattern.findall(Value) + for Ref in MacroReference: + if Ref not in self.MacroDictionary: + return False, Ref + Value = Value.replace(Ref, self.MacroDictionary[Ref]) + + return True, Value + +## ToolDefDict +# +# Load tools_def.txt in input workspace dir +# +# @param WorkSpace: Workspace dir +# +# @retval ToolDef An instance of ToolDefClassObject() with loaded tools_def.txt +# +def ToolDefDict(WorkSpace): + Target = TargetTxtDict(WorkSpace) + ToolDef = ToolDefClassObject() + if DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF in Target.TargetTxtDictionary: + gDefaultToolsDefFile = Target.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF] + ToolDef.LoadToolDefFile(os.path.normpath(os.path.join(WorkSpace, gDefaultToolsDefFile))) + return ToolDef + +## +# +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +# +if __name__ == '__main__': + ToolDef = ToolDefDict(os.getenv("WORKSPACE")) + pass diff --git a/BaseTools/Source/Python/Common/XmlParser.py b/BaseTools/Source/Python/Common/XmlParser.py new file mode 100644 index 0000000000..4d60115925 --- /dev/null +++ b/BaseTools/Source/Python/Common/XmlParser.py @@ -0,0 +1,1754 @@ +## @file +# This file is used to parse a xml file of .PKG file +# +# Copyright (c) 2008, 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 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 +# +from xml.dom import minidom +from XmlRoutines import * +from CommonDataClass.DistributionPackageClass import * +from CommonDataClass.PackageClass import * +from CommonDataClass.ModuleClass import * +from Common.String import GetStringOfList + +# +# Get Help Text +# +def GetHelpTextList(HelpText): + HelpTextList = [] + for HT in HelpText: + HelpTextObj = HelpTextClass() + HelpTextObj.Lang = HT.Lang + HelpTextObj.String = HT.HelpText + HelpTextList.append(HelpTextObj) + return HelpTextList + +# HeaderXml +class HeaderXml(object): + def __init__(self): + self.Name = '' + self.BaseName = '' + self.GUID = '' + self.Version = '' + self.Copyright = '' + self.License = '' + self.Abstract = '' + self.Description = '' + + def FromXml(self, Item, Key): + self.Name = XmlElement(Item, '%s/Name' % Key) + self.BaseName = XmlAttribute(XmlNode(Item, '%s/Name' % Key), 'BaseName') + self.GUID = XmlElement(Item, '%s/GUID' % Key) + self.Version = XmlAttribute(XmlNode(Item, '%s/GUID' % Key), 'Version') + self.Copyright = XmlElement(Item, '%s/Copyright' % Key) + self.License = XmlElement(Item, '%s/License' % Key) + self.Abstract = XmlElement(Item, '%s/Abstract' % Key) + self.Description = XmlElement(Item, '%s/Description' % Key) + + ModuleHeader = ModuleHeaderClass() + ModuleHeader.Name = self.Name + ModuleHeader.BaseName = self.BaseName + ModuleHeader.Guid = self.GUID + ModuleHeader.Version = self.Version + ModuleHeader.Copyright = self.Copyright + ModuleHeader.License = self.License + ModuleHeader.Abstract = self.Abstract + ModuleHeader.Description = self.Description + + return ModuleHeader + + def ToXml(self, Header, Key): + Element1 = CreateXmlElement('Name', Header.Name, [], [['BaseName', Header.BaseName]]) + Element2 = CreateXmlElement('GUID', Header.Guid, [], [['Version', Header.Version]]) + AttributeList = [] + NodeList = [Element1, + Element2, + ['Abstract', Header.Abstract], + ['Copyright', Header.Copyright], + ['License', Header.License], + ['Description', Header.Description], + ] + Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) + + return Root + + def __str__(self): + return "Name = %s BaseName = %s GUID = %s Version = %s Copyright = %s License = %s Abstract = %s Description = %s" \ + % (self.Name, self.BaseName, self.GUID, self.Version, self.Copyright, self.License, self.Abstract, self.Description) + +# DistributionPackageHeaderXml +class DistributionPackageHeaderXml(object): + def __init__(self): + self.Header = HeaderXml() + self.ReadOnly = False + self.RePackage = True + self.Vendor = '' + self.Date = '' + self.Signature = '' + self.XmlSpecification = '' + + def FromXml(self, Item, Key): + self.ReadOnly = XmlAttribute(XmlNode(Item, '%s' % Key), 'ReadOnly') + self.RePackage = XmlAttribute(XmlNode(Item, '%s' % Key), 'RePackage') + self.Vendor = XmlElement(Item, '%s/Vendor' % Key) + self.Date = XmlElement(Item, '%s/Date' % Key) + self.Signature = XmlElement(Item, '%s/Signature' % Key) + self.XmlSpecification = XmlElement(Item, '%s/XmlSpecification' % Key) + self.Header.FromXml(Item, Key) + + DistributionPackageHeader = DistributionPackageHeaderClass() + DistributionPackageHeader.ReadOnly = self.ReadOnly + DistributionPackageHeader.RePackage = self.RePackage + DistributionPackageHeader.Name = self.Header.Name + DistributionPackageHeader.BaseName = self.Header.BaseName + DistributionPackageHeader.Guid = self.Header.GUID + DistributionPackageHeader.Version = self.Header.Version + DistributionPackageHeader.Vendor = self.Vendor + DistributionPackageHeader.Date = self.Date + DistributionPackageHeader.Copyright = self.Header.Copyright + DistributionPackageHeader.License = self.Header.License + DistributionPackageHeader.Abstract = self.Header.Abstract + DistributionPackageHeader.Description = self.Header.Description + DistributionPackageHeader.Signature = self.Signature + DistributionPackageHeader.XmlSpecification = self.XmlSpecification + + return DistributionPackageHeader + + def ToXml(self, DistributionPackageHeader, Key): + Element1 = CreateXmlElement('Name', DistributionPackageHeader.Name, [], [['BaseName', DistributionPackageHeader.BaseName]]) + Element2 = CreateXmlElement('GUID', DistributionPackageHeader.Guid, [], [['Version', DistributionPackageHeader.Version]]) + AttributeList = [['ReadOnly', str(DistributionPackageHeader.ReadOnly)], ['RePackage', str(DistributionPackageHeader.RePackage)]] + NodeList = [Element1, + Element2, + ['Vendor', DistributionPackageHeader.Vendor], + ['Date', DistributionPackageHeader.Date], + ['Copyright', DistributionPackageHeader.Copyright], + ['License', DistributionPackageHeader.License], + ['Abstract', DistributionPackageHeader.Abstract], + ['Description', DistributionPackageHeader.Description], + ['Signature', DistributionPackageHeader.Signature], + ['XmlSpecification', DistributionPackageHeader.XmlSpecification], + ] + Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) + + return Root + + def __str__(self): + return "ReadOnly = %s RePackage = %s Vendor = %s Date = %s Signature = %s XmlSpecification = %s %s" \ + % (self.ReadOnly, self.RePackage, self.Vendor, self.Date, self.Signature, self.XmlSpecification, self.Header) + +# PackageHeaderXml +class PackageHeaderXml(object): + def __init__(self): + self.Header = HeaderXml() + self.PackagePath = '' + + def FromXml(self, Item, Key): + self.PackagePath = XmlElement(Item, '%s/PackagePath' % Key) + self.Header.FromXml(Item, Key) + + PackageHeader = PackageHeaderClass() + PackageHeader.Name = self.Header.Name + PackageHeader.BaseName = self.Header.BaseName + PackageHeader.Guid = self.Header.GUID + PackageHeader.Version = self.Header.Version + PackageHeader.Copyright = self.Header.Copyright + PackageHeader.License = self.Header.License + PackageHeader.Abstract = self.Header.Abstract + PackageHeader.Description = self.Header.Description + PackageHeader.CombinePath = self.PackagePath + + return PackageHeader + + def ToXml(self, PackageHeader, Key): + Element1 = CreateXmlElement('Name', PackageHeader.Name, [], [['BaseName', PackageHeader.BaseName]]) + Element2 = CreateXmlElement('GUID', PackageHeader.Guid, [], [['Version', PackageHeader.Version]]) + AttributeList = [] + NodeList = [Element1, + Element2, + ['Copyright', PackageHeader.Copyright], + ['License', PackageHeader.License], + ['Abstract', PackageHeader.Abstract], + ['Description', PackageHeader.Description], + ['PackagePath', PackageHeader.CombinePath], + ] + Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) + + return Root + + def __str__(self): + return "PackagePath = %s %s" \ + % (self.PackagePath, self.Header) + +# ClonedFromXml +class ClonedFromXml(object): + def __init__(self): + self.GUID = '' + self.Version = '' + + def FromXml(self, Item, Key): + self.GUID = XmlElement(Item, '%s/GUID' % Key) + self.Version = XmlAttribute(XmlNode(Item, '%s/GUID' % Key), 'Version') + + if self.GUID == '' and self.Version == '': + return None + + ClonedFrom = ClonedRecordClass() + ClonedFrom.PackageGuid = self.GUID + ClonedFrom.PackageVersion = self.Version + + return ClonedFrom + + def ToXml(self, ClonedFrom, Key): + Root = minidom.Document() + Element1 = CreateXmlElement('GUID', ClonedFrom.PackageGuid, [], [['Version', ClonedFrom.PackageVersion]]) + AttributeList = [] + NodeList = [Element1] + Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) + + return Root + + def __str__(self): + return "GUID = %s Version = %s" % (self.GUID, self.Version) + +# CommonDefinesXml +class CommonDefinesXml(object): + def __init__(self): + self.Usage = '' + self.SupArchList = '' + self.SupModList = '' + self.FeatureFlag = '' + + def FromXml(self, Item, Key): + self.Usage = XmlAttribute(Item, 'Usage') + self.SupArchList = XmlAttribute(Item, 'SupArchList') + self.SupModList = XmlAttribute(Item, 'SupModList') + self.FeatureFlag = XmlAttribute(Item, 'FeatureFlag') + + def ToXml(self): + pass + + def __str__(self): + return "Usage = %s SupArchList = %s SupModList = %s FeatureFlag = %s" % (self.Usage, self.SupArchList, self.SupModList, self.FeatureFlag) + +# HelpTextXml +class HelpTextXml(object): + def __init__(self): + self.HelpText = '' + self.Lang = '' + + def FromXml(self, Item, Key): + self.HelpText = XmlElement(Item, 'HelpText') + self.Lang = XmlAttribute(Item, 'Lang') + + def ToXml(self, HelpText, Key = 'HelpText'): + return CreateXmlElement('%s' % Key, HelpText.String, [], [['Lang', HelpText.Lang]]) + + def __str__(self): + return "HelpText = %s Lang = %s" % (self.HelpText, self.Lang) + +# LibraryClassXml +class LibraryClassXml(object): + def __init__(self): + self.Keyword = '' + self.HeaderFile = '' + self.RecommendedInstanceGuid = '' + self.RecommendedInstanceVersion = '' + self.CommonDefines = CommonDefinesXml() + self.HelpText = [] + + def FromXml(self, Item, Key): + self.Keyword = XmlAttribute(XmlNode(Item, '%s' % Key), 'Keyword') + if self.Keyword == '': + self.Keyword = XmlElement(Item, '%s/Keyword' % Key) + self.HeaderFile = XmlElement(Item, '%s/HeaderFile' % Key) + self.RecommendedInstanceGuid = XmlElement(Item, '%s/RecommendedInstance/GUID' % Key) + self.RecommendedInstanceVersion = XmlAttribute(XmlNode(Item, '%s/RecommendedInstance/GUID' % Key), 'Version') + self.CommonDefines.FromXml(XmlNode(Item, '%s' % Key), Key) + for HelpTextItem in XmlList(Item, '%s/HelpText' % Key): + HelpTextObj = HelpTextXml() + HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key) + self.HelpText.append(HelpTextObj) + + LibraryClass = LibraryClassClass() + LibraryClass.LibraryClass = self.Keyword + LibraryClass.IncludeHeader = self.HeaderFile + LibraryClass.SupArchList = self.CommonDefines.SupArchList + LibraryClass.SupModuleList = self.CommonDefines.SupModList + LibraryClass.RecommendedInstanceGuid = self.RecommendedInstanceGuid + LibraryClass.RecommendedInstanceVersion = self.RecommendedInstanceVersion + LibraryClass.HelpTextList = GetHelpTextList(self.HelpText) + + return LibraryClass + + def ToXml(self, LibraryClass, Key): + Element1 = CreateXmlElement('GUID', LibraryClass.RecommendedInstanceGuid, [], [['Version', LibraryClass.RecommendedInstanceVersion]]) + Element2 = CreateXmlElement('RecommendedInstance', '', [Element1], []) + AttributeList = [['Keyword', LibraryClass.LibraryClass], + ['SupArchList', GetStringOfList(LibraryClass.SupArchList)], + ['SupModList', GetStringOfList(LibraryClass.SupModuleList)] + ] + NodeList = [['HeaderFile', LibraryClass.IncludeHeader], + Element2 + ] + for Item in LibraryClass.HelpTextList: + Tmp = HelpTextXml() + NodeList.append(Tmp.ToXml(Item)) + Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) + + return Root + + def __str__(self): + Str = "Keyword = %s HeaderFile = %s RecommendedInstanceGuid = %s RecommendedInstanceVersion = %s %s" \ + % (self.Keyword, self.HeaderFile, self.RecommendedInstanceGuid, self.RecommendedInstanceVersion, \ + self.CommonDefines) + for Item in self.HelpText: + Str = Str + "\n\t" + str(Item) + return Str + +# IndustryStandardHeaderXml +class IndustryStandardHeaderXml(object): + def __init__(self): + self.HeaderFile = '' + self.HelpText = [] + + def FromXml(self, Item, Key): + self.HeaderFile = XmlElement(Item, '%s/HeaderFile' % Key) + for HelpTextItem in XmlList(Item, '%s/HelpText' % Key): + HelpTextObj = HelpTextXml() + HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key) + self.HelpText.append(HelpTextObj) + + Include = IncludeClass() + Include.FilePath = self.HeaderFile + Include.HelpTextList = GetHelpTextList(self.HelpText) + + return Include + + def ToXml(self, IndustryStandardHeader, Key): + AttributeList = [] + NodeList = [['HeaderFile', IndustryStandardHeader.FilePath]] + for Item in IndustryStandardHeader.HelpTextList: + Tmp = HelpTextXml() + NodeList.append(Tmp.ToXml(Item)) + Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) + + return Root + + def __str__(self): + Str = "HeaderFile = %s" % (self.HeaderFile) + for Item in self.HelpText: + Str = Str + "\n\t" + str(Item) + return Str + +# PackageIncludeHeaderXml +class PackageIncludeHeaderXml(object): + def __init__(self): + self.HeaderFile = '' + self.CommonDefines = CommonDefinesXml() + self.HelpText = [] + + def FromXml(self, Item, Key): + self.HeaderFile = XmlElement(Item, '%s/HeaderFile' % Key) + self.CommonDefines.FromXml(XmlNode(Item, '%s/HeaderFile' % Key), Key) + for HelpTextItem in XmlList(Item, '%s/HelpText' % Key): + HelpTextObj = HelpTextXml() + HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key) + self.HelpText.append(HelpTextObj) + + Include = IncludeClass() + Include.FilePath = self.HeaderFile + Include.SupArchList = self.CommonDefines.SupArchList + Include.SupModuleList = self.CommonDefines.SupModList + Include.HelpTextList = GetHelpTextList(self.HelpText) + + return Include + + def ToXml(self, PackageIncludeHeader, Key): + AttributeList = [['SupArchList', PackageIncludeHeader.SupArchList], + ['SupModList', PackageIncludeHeader.SupModuleList] + ] + NodeList = [['HeaderFile', PackageIncludeHeader.FilePath]] + for Item in PackageIncludeHeader.HelpTextList: + Tmp = HelpTextXml() + NodeList.append(Tmp.ToXml(Item)) + Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) + + return Root + + def __str__(self): + Str = "HeaderFile = %s\n\t%s" % (self.HeaderFile, self.CommonDefines) + for Item in self.HelpText: + Str = Str + "\n\t" + str(Item) + return Str + +#GUID/Protocol/Ppi +class GuidProtocolPpiXml(object): + def __init__(self): + self.UiName = '' + self.GuidTypes = '' + self.Notify = '' + self.CName = '' + self.GuidValue = '' + self.CommonDefines = CommonDefinesXml() + self.HelpText = [] + + def FromXml(self, Item, Key): + self.UiName = XmlAttribute(XmlNode(Item, '%s' % Key), 'UiName') + self.GuidTypes = XmlAttribute(XmlNode(Item, '%s' % Key), 'GuidTypes') + self.GuidType = XmlAttribute(XmlNode(Item, '%s' % Key), 'GuidType') + self.Notify = XmlAttribute(XmlNode(Item, '%s' % Key), 'Notify') + self.CName = XmlElement(Item, '%s/CName' % Key) + self.GuidValue = XmlElement(Item, '%s/GuidValue' % Key) + self.VariableName = XmlElement(Item, '%s/VariableName' % Key) + self.CommonDefines.FromXml(XmlNode(Item, '%s' % Key), Key) + for HelpTextItem in XmlList(Item, '%s/HelpText' % Key): + HelpTextObj = HelpTextXml() + HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key) + self.HelpText.append(HelpTextObj) + + GuidProtocolPpi = GuidProtocolPpiCommonClass() + GuidProtocolPpi.Name = self.UiName + GuidProtocolPpi.CName = self.CName + GuidProtocolPpi.Guid = self.GuidValue + GuidProtocolPpi.VariableName = self.VariableName + GuidProtocolPpi.Notify = self.Notify + GuidProtocolPpi.Usage = self.CommonDefines.Usage + GuidProtocolPpi.FeatureFlag = self.CommonDefines.FeatureFlag + GuidProtocolPpi.SupArchList = self.CommonDefines.SupArchList + GuidProtocolPpi.SupModuleList = self.CommonDefines.SupModList + GuidProtocolPpi.GuidTypeLists = self.GuidTypes + GuidProtocolPpi.GuidTypeList = self.GuidType + GuidProtocolPpi.HelpTextList = GetHelpTextList(self.HelpText) + + return GuidProtocolPpi + + def ToXml(self, GuidProtocolPpi, Key): + AttributeList = [['Usage', GetStringOfList(GuidProtocolPpi.Usage)], + ['UiName', GuidProtocolPpi.Name], + ['GuidTypes', GetStringOfList(GuidProtocolPpi.GuidTypeLists)], + ['GuidType', GetStringOfList(GuidProtocolPpi.GuidTypeList)], + ['Notify', str(GuidProtocolPpi.Notify)], + ['SupArchList', GetStringOfList(GuidProtocolPpi.SupArchList)], + ['SupModList', GetStringOfList(GuidProtocolPpi.SupModuleList)], + ['FeatureFlag', GuidProtocolPpi.FeatureFlag] + ] + NodeList = [['CName', GuidProtocolPpi.CName], + ['GuidValue', GuidProtocolPpi.Guid], + ['VariableName', GuidProtocolPpi.VariableName] + ] + for Item in GuidProtocolPpi.HelpTextList: + Tmp = HelpTextXml() + NodeList.append(Tmp.ToXml(Item)) + Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) + + return Root + + def __str__(self): + Str = "UiName = %s Notify = %s GuidTypes = %s CName = %s GuidValue = %s %s" \ + % (self.UiName, self.Notify, self.GuidTypes, self.CName, self.GuidValue, self.CommonDefines) + for Item in self.HelpText: + Str = Str + "\n\t" + str(Item) + return Str + +# PcdErrorXml +class PcdErrorXml(object): + def __init__(self): + self.ValidValueList = '' + self.ValidValueListLang = '' + self.ValidValueRange = '' + self.Expression = '' + self.ErrorNumber = '' + self.ErrorMessage = [] + + def FromXml(self, Item, Key): + self.ValidValueList = XmlElement(Item, '%s/ValidValueList' % Key) + self.ValidValueListLang = XmlAttribute(XmlNode(Item, '%s/ValidValueList' % Key), 'Lang') + self.ValidValueRange = XmlElement(Item, '%s/ValidValueRange' % Key) + self.Expression = XmlElement(Item, '%s/Expression' % Key) + self.ErrorNumber = XmlElement(Item, '%s/ErrorNumber' % Key) + for ErrMsg in XmlList(Item, '%s/ErrorMessage' % Key): + ErrorMessageString = XmlElement(ErrMsg, 'ErrorMessage') + ErrorMessageLang = XmlAttribute(XmlNode(ErrMsg, 'ErrorMessage'), 'Lang') + self.ErrorMessage.append((ErrorMessageLang, ErrorMessageString)) + + Error = PcdErrorClass() + Error.ValidValueList = self.ValidValueList + Error.ValidValueListLang = self.ValidValueListLang + Error.ValidValueRange = self.ValidValueRange + Error.Expression = self.Expression + Error.ErrorNumber = self.ErrorNumber + Error.ErrorMessage = self.ErrorMessage + + return Error + + def ToXml(self, PcdError, Key): + AttributeList = [] + Element1 = CreateXmlElement('ValidValueList', PcdError.ValidValueList, [], [['Lang', PcdError.ValidValueListLang]]) + NodeList = [Element1, + ['ValidValueRange', PcdError.ValidValueRange], + ['Expression', PcdError.Expression], + ['ErrorNumber', PcdError.ErrorNumber], + ] + for Item in PcdError.ErrorMessage: + Element = CreateXmlElement('ErrorMessage', Item[1], [], [['Lang', Item[0]]]) + NodeList.append(Element) + Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) + + return Root + + def __str__(self): + return "ValidValueList = %s ValidValueListLang = %s ValidValueRange = %s Expression = %s ErrorNumber = %s %s" \ + % (self.ValidValueList, self.ValidValueListLang, self.ValidValueRange, self.Expression, self.ErrorNumber, self.ErrorMessage) + +# PcdEntryXml +class PcdEntryXml(object): + def __init__(self): + self.PcdItemType = '' + self.PcdUsage = '' + self.TokenSpaceGuidCName = '' + self.TokenSpaceGuidValue = '' + self.Token = '' + self.CName = '' + self.PcdCName = '' + self.DatumType = '' + self.ValidUsage = '' + self.DefaultValue = '' + self.MaxDatumSize = '' + self.Value = '' + self.Offset = '' + self.CommonDefines = CommonDefinesXml() + self.HelpText = [] + self.PcdError = [] + + def FromXml(self, Item, Key): + self.PcdItemType = XmlAttribute(XmlNode(Item, '%s' % Key), 'PcdItemType') + self.PcdUsage = XmlAttribute(XmlNode(Item, '%s' % Key), 'PcdUsage') + self.TokenSpaceGuidCName = XmlElement(Item, '%s/TokenSpaceGuidCName' % Key) + self.TokenSpaceGuidValue = XmlElement(Item, '%s/TokenSpaceGuidValue' % Key) + self.Token = XmlElement(Item, '%s/Token' % Key) + self.CName = XmlElement(Item, '%s/CName' % Key) + self.PcdCName = XmlElement(Item, '%s/PcdCName' % Key) + self.DatumType = XmlElement(Item, '%s/DatumType' % Key) + self.ValidUsage = XmlElement(Item, '%s/ValidUsage' % Key) + self.DefaultValue = XmlElement(Item, '%s/DefaultValue' % Key) + self.MaxDatumSize = XmlElement(Item, '%s/MaxDatumSize' % Key) + self.Value = XmlElement(Item, '%s/Value' % Key) + self.Offset = XmlElement(Item, '%s/Offset' % Key) + self.CommonDefines.FromXml(XmlNode(Item, '%s' % Key), Key) + for HelpTextItem in XmlList(Item, '%s/HelpText' % Key): + HelpTextObj = HelpTextXml() + HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key) + self.HelpText.append(HelpTextObj) + for PcdErrorItem in XmlList(Item, '%s/PcdError' % Key): + PcdErrorObj = PcdErrorXml() + PcdErrorObj.FromXml(PcdErrorItem, 'PcdError') + self.PcdError.append(PcdErrorObj) + + PcdEntry = PcdClass() + PcdEntry.SupArchList = self.CommonDefines.SupArchList + PcdEntry.SupModuleList = self.CommonDefines.SupModList + PcdEntry.TokenSpaceGuidCName = self.TokenSpaceGuidCName + PcdEntry.TokenSpaceGuidValue = self.TokenSpaceGuidValue + PcdEntry.Token = self.Token + PcdEntry.CName = self.CName + PcdEntry.PcdCName = self.PcdCName + PcdEntry.DatumType = self.DatumType + PcdEntry.ValidUsage = self.ValidUsage + PcdEntry.PcdUsage = self.PcdUsage + PcdEntry.Usage = self.CommonDefines.Usage + PcdEntry.DefaultValue = self.DefaultValue + PcdEntry.Value = self.Value + PcdEntry.Offset = self.Offset + PcdEntry.MaxDatumSize = self.MaxDatumSize + PcdEntry.FeatureFlag = self.CommonDefines.FeatureFlag + PcdEntry.PcdItemType = self.PcdItemType + PcdEntry.HelpTextList = GetHelpTextList(self.HelpText) + PcdEntry.PcdErrors = self.PcdError + + return PcdEntry + + def ToXml(self, PcdEntry, Key): + AttributeList = [['SupArchList', GetStringOfList(PcdEntry.SupArchList)], + ['PcdUsage', PcdEntry.PcdUsage], + ['PcdItemType', PcdEntry.PcdItemType], + ['FeatureFlag', PcdEntry.FeatureFlag], + ['SupModList', GetStringOfList(PcdEntry.SupModuleList)] + ] + NodeList = [['TokenSpaceGuidCName', PcdEntry.TokenSpaceGuidCName], + ['TokenSpaceGuidValue', PcdEntry.TokenSpaceGuidValue], + ['Token', PcdEntry.Token], + ['CName', PcdEntry.CName], + ['PcdCName', PcdEntry.PcdCName], + ['DatumType', PcdEntry.DatumType], + ['ValidUsage', GetStringOfList(PcdEntry.ValidUsage)], + ['DefaultValue', PcdEntry.DefaultValue], + ['Value', PcdEntry.Value], + ['Offset', PcdEntry.Offset], + ['MaxDatumSize', PcdEntry.MaxDatumSize], + ] + for Item in PcdEntry.HelpTextList: + Tmp = HelpTextXml() + NodeList.append(Tmp.ToXml(Item, 'HelpText')) + for Item in PcdEntry.PcdErrors: + Tmp = PcdErrorXml() + NodeList.append(Tmp.ToXml(Item, 'PcdError')) + + Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) + + return Root + + def __str__(self): + Str = "PcdItemType = %s PcdUsage = %s TokenSpaceGuidCName = %s TokenSpaceGuidValue = %s Token = %s CName = %s PcdCName = %s DatumType = %s ValidUsage = %s DefaultValue = %s MaxDatumSize = %s Value = %s Offset = %s %s" \ + % (self.PcdItemType, self.PcdUsage, self.TokenSpaceGuidCName, self.TokenSpaceGuidValue, self.Token, self.CName, self.PcdCName, self.DatumType, self.ValidUsage, self.DefaultValue, self.MaxDatumSize, self.Value, self.Offset, self.CommonDefines) + for Item in self.HelpText: + Str = Str + "\n\t" + str(Item) + for Item in self.PcdError: + Str = Str + "\n\tPcdError:" + str(Item) + return Str + +# PcdCheckXml +class PcdCheckXml(object): + def __init__(self): + self.PcdCheck = '' + + def FromXml(self, Item, Key): + self.PcdCheck = XmlElement(Item, 'PcdCheck') + + return self.PcdCheck + + def ToXml(self, PcdCheck, Key): + Root = CreateXmlElement('%s' % Key, PcdCheck, [], []) + return Root + + def __str__(self): + return "PcdCheck = %s" % (self.PcdCheck) + +# MiscellaneousFileXml +class MiscellaneousFileXml(object): + def __init__(self): + self.Header = HeaderXml() + self.Files = [] + + def FromXml(self, Item, Key): + self.Header.FromXml(Item, Key) + NewItem = XmlNode(Item, '%s/Header' % Key) + self.Header.FromXml(NewItem, 'Header') + + for SubItem in XmlList(Item, '%s/Filename' % Key): + Filename = XmlElement(SubItem, '%s/Filename' % Key) + Executable = XmlAttribute(XmlNode(SubItem, '%s/Filename' % Key), 'Executable') + self.Files.append([Filename, Executable]) + + MiscFile = MiscFileClass() + MiscFile.Copyright = self.Header.Copyright + MiscFile.License = self.Header.License + MiscFile.Abstract = self.Header.Abstract + MiscFile.Description = self.Header.Description + for File in self.Files: + FileObj = FileClass() + FileObj.Filename = File[0] + FileObj.Executable = File[1] + MiscFile.Files.append(FileObj) + + return MiscFile + + def FromXml2(self, Item, Key): + NewItem = XmlNode(Item, '%s/Header' % Key) + self.Header.FromXml(NewItem, 'Header') + + for SubItem in XmlList(Item, '%s/Filename' % Key): + Filename = XmlElement(SubItem, '%s/Filename' % Key) + Executable = XmlAttribute(XmlNode(SubItem, '%s/Filename' % Key), 'Executable') + self.Files.append([Filename, Executable]) + + MiscFile = MiscFileClass() + MiscFile.Name = self.Header.Name + MiscFile.Copyright = self.Header.Copyright + MiscFile.License = self.Header.License + MiscFile.Abstract = self.Header.Abstract + MiscFile.Description = self.Header.Description + for File in self.Files: + FileObj = FileClass() + FileObj.Filename = File[0] + FileObj.Executable = File[1] + MiscFile.Files.append(FileObj) + + return MiscFile + + + def ToXml(self, MiscFile, Key): + if MiscFile: + NodeList = [['Copyright', MiscFile.Copyright], + ['License', MiscFile.License], + ['Abstract', MiscFile.Abstract], + ['Description', MiscFile.Description], + ] + if MiscFile != None: + for File in MiscFile.Files: + NodeList.append(CreateXmlElement('Filename', File.Filename, [], [['Executable', File.Executable]])) + Root = CreateXmlElement('%s' % Key, '', NodeList, []) + + return Root + + def ToXml2(self, MiscFile, Key): + if MiscFile: + NodeList = [['Name', MiscFile.Name], + ['Copyright', MiscFile.Copyright], + ['License', MiscFile.License], + ['Abstract', MiscFile.Abstract], + ['Description', MiscFile.Description], + ] + HeaderNode = CreateXmlElement('Header', '', NodeList, []) + NodeList = [HeaderNode] + + for File in MiscFile.Files: + NodeList.append(CreateXmlElement('Filename', File.Filename, [], [['Executable', File.Executable]])) + Root = CreateXmlElement('%s' % Key, '', NodeList, []) + + return Root + + def __str__(self): + Str = str(self.Header) + for Item in self.Files: + Str = Str + '\n\tFilename:' + str(Item) + return Str + +# UserExtensionsXml +class UserExtensionsXml(object): + def __init__(self): + self.UserId = '' + self.Identifier = '' + self.Defines = [] + self.BuildOptions = [] + + def FromXml(self, Item, Key): + self.UserId = XmlAttribute(XmlNode(Item, '%s' % Key), 'UserId') + self.Identifier = XmlAttribute(XmlNode(Item, '%s' % Key), 'Identifier') + for SubItem in XmlList(Item, '%s/Define' % Key): + self.Defines.append(XmlElement(SubItem, '%s/Define' % Key)) + for SubItem in XmlList(Item, '%s/BuildOption' % Key): + self.BuildOptions.append(XmlElement(SubItem, '%s/BuildOption' % Key)) + + UserExtension = UserExtensionsClass() + UserExtension.UserID = self.UserId + UserExtension.Identifier = self.Identifier + UserExtension.Defines = self.Defines + UserExtension.BuildOptions = self.BuildOptions + + return UserExtension + + def ToXml(self, UserExtension, Key): + AttributeList = [['UserId', str(UserExtension.UserID)], + ['Identifier', str(UserExtension.Identifier)] + ] + NodeList = [] + for Item in UserExtension.Defines: + NodeList.append(['Define', Item]) + for Item in UserExtension.BuildOptions: + NodeList.append(['BuildOption', Item]) + Root = CreateXmlElement('%s' % Key, UserExtension.Content, NodeList, AttributeList) + + return Root + + def __str__(self): + Str = "UserId = %s Identifier = %s" % (self.UserId, self.Identifier) + Str = Str + '\n\tDefines:' + str(self.Defines) + Str = Str + '\n\tBuildOptions:' + str(self.BuildOptions) + return Str + +# BootModeXml +class BootModeXml(object): + def __init__(self): + self.SupportedBootModes = '' + self.CommonDefines = CommonDefinesXml() + self.HelpText = [] + + def FromXml(self, Item, Key): + self.SupportedBootModes = XmlElement(Item, '%s/SupportedBootModes' % Key) + self.CommonDefines.FromXml(Item, Key) + for HelpTextItem in XmlList(Item, '%s/HelpText' % Key): + HelpTextObj = HelpTextXml() + HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key) + self.HelpText.append(HelpTextObj) + + BootMode = ModuleBootModeClass() + BootMode.Name = self.SupportedBootModes + BootMode.SupArchList = self.CommonDefines.SupArchList + BootMode.Usage = self.CommonDefines.Usage + BootMode.FeatureFlag = self.CommonDefines.FeatureFlag + BootMode.HelpTextList = GetHelpTextList(self.HelpText) + + return BootMode + + def ToXml(self, BootMode, Key): + AttributeList = [['Usage', BootMode.Usage], + ['SupArchList', GetStringOfList(BootMode.SupArchList)], + ['FeatureFlag', BootMode.FeatureFlag], + ] + NodeList = [['SupportedBootModes', BootMode.Name]] + for Item in BootMode.HelpTextList: + Tmp = HelpTextXml() + NodeList.append(Tmp.ToXml(Item, 'HelpText')) + Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) + + return Root + + def __str__(self): + Str = "SupportedBootModes = %s %s" % (self.SupportedBootModes, self.CommonDefines) + for Item in self.HelpText: + Str = Str + '\n\t' + str(Item) + return Str + +# EventXml +class EventXml(object): + def __init__(self): + self.EventType = '' + self.Name = '' + self.CommonDefines = CommonDefinesXml() + self.HelpText = [] + + def FromXml(self, Item, Key): + self.EventType = XmlAttribute(XmlNode(Item, '%s' % Key), 'EventType') + self.Name = XmlElement(Item, '%s' % Key) + self.CommonDefines.FromXml(Item, Key) + for HelpTextItem in XmlList(Item, '%s/HelpText' % Key): + HelpTextObj = HelpTextXml() + HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key) + self.HelpText.append(HelpTextObj) + + Event = ModuleEventClass() + Event.Type = self.EventType + Event.GuidCName = self.Name + Event.SupArchList = self.CommonDefines.SupArchList + Event.Usage = self.CommonDefines.Usage + Event.FeatureFlag = self.CommonDefines.FeatureFlag + Event.HelpTextList = GetHelpTextList(self.HelpText) + + return Event + + def ToXml(self, Event, Key): + AttributeList = [['EventType', Event.Type], + ['Usage', Event.Usage], + ['SupArchList', GetStringOfList(Event.SupArchList)], + ['FeatureFlag', Event.FeatureFlag], + ] + NodeList = [] + for Item in Event.HelpTextList: + Tmp = HelpTextXml() + NodeList.append(Tmp.ToXml(Item, 'HelpText')) + Root = CreateXmlElement('%s' % Key, Event.GuidCName, NodeList, AttributeList) + + return Root + + def __str__(self): + Str = "EventType = %s %s" % (self.EventType, self.CommonDefines) + for Item in self.HelpText: + Str = Str + '\n\t' + str(Item) + return Str + +# HobXml +class HobXml(object): + def __init__(self): + self.HobType = '' + self.Name = '' + self.CommonDefines = CommonDefinesXml() + self.HelpText = [] + + def FromXml(self, Item, Key): + self.HobType = XmlAttribute(XmlNode(Item, '%s' % Key), 'HobType') + self.Name = XmlElement(Item, '%s' % Key) + self.CommonDefines.FromXml(Item, Key) + for HelpTextItem in XmlList(Item, '%s/HelpText' % Key): + HelpTextObj = HelpTextXml() + HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key) + self.HelpText.append(HelpTextObj) + + Hob = ModuleHobClass() + Hob.Type = self.HobType + Hob.GuidCName = self.Name + Hob.SupArchList = self.CommonDefines.SupArchList + Hob.Usage = self.CommonDefines.Usage + Hob.FeatureFlag = self.CommonDefines.FeatureFlag + Hob.HelpTextList = GetHelpTextList(self.HelpText) + + return Hob + + def ToXml(self, Hob, Key): + AttributeList = [['EventType', Hob.Type], + ['Usage', Hob.Usage], + ['SupArchList', GetStringOfList(Hob.SupArchList)], + ['FeatureFlag', Hob.FeatureFlag], + ] + NodeList = [] + for Item in Hob.HelpTextList: + Tmp = HelpTextXml() + NodeList.append(Tmp.ToXml(Item, 'HelpText')) + Root = CreateXmlElement('%s' % Key, Hob.GuidCName, NodeList, AttributeList) + + return Root + + def __str__(self): + Str = "HobType = %s %s" % (self.HobType, self.CommonDefines) + for Item in self.HelpText: + Str = Str + '\n\t' + str(Item) + return Str + +# ModulePropertyXml +class ModulePropertyXml(object): + def __init__(self): + self.CommonDefines = CommonDefinesXml() + self.ModuleType = '' + self.Path = '' + self.PcdIsDriver = '' + self.UefiSpecificationVersion = '' + self.PiSpecificationVersion = '' + self.Specification = '' + self.SpecificationVersion = '' + self.BootModes = [] + self.Events = [] + self.HOBs = [] + + def FromXml(self, Item, Key, Header = None): + self.CommonDefines.FromXml(Item, Key) + self.ModuleType = XmlElement(Item, '%s/ModuleType' % Key) + self.Path = XmlElement(Item, '%s/Path' % Key) + self.PcdIsDriver = XmlElement(Item, '%s/PcdIsDriver' % Key) + self.UefiSpecificationVersion = XmlElement(Item, '%s/UefiSpecificationVersion' % Key) + self.PiSpecificationVersion = XmlElement(Item, '%s/PiSpecificationVersion' % Key) + self.Specification = XmlElement(Item, '%s/Specification' % Key) + self.SpecificationVersion = XmlAttribute(XmlNode(Item, '%s/Specification' % Key), 'Version') + for SubItem in XmlList(Item, '%s/BootMode' % Key): + A = BootModeXml() + BootMode = A.FromXml(SubItem, 'BootMode') + self.BootModes.append(BootMode) + for SubItem in XmlList(Item, '%s/Event' % Key): + A = EventXml() + Event = A.FromXml(SubItem, 'Event') + self.Events.append(Event) + for SubItem in XmlList(Item, '%s/HOB' % Key): + A = HobXml() + Hob = A.FromXml(SubItem, 'HOB') + self.HOBs.append(Hob) + + if Header == None: + Header = ModuleHeaderClass() + + Header.ModuleType = self.ModuleType + Header.SupArchList = self.CommonDefines.SupArchList + Header.SupModuleList = self.CommonDefines.SupModList + Header.CombinePath = self.Path + Header.PcdIsDriver = self.PcdIsDriver + Header.UefiSpecificationVersion = self.UefiSpecificationVersion + Header.PiSpecificationVersion = self.PiSpecificationVersion + + return Header, self.BootModes, self.Events, self.HOBs + + + def ToXml(self, Header, BootModes, Events, Hobs, Key): + AttributeList = [['SupArchList', GetStringOfList(Header.SupArchList)], + ['SupModList', GetStringOfList(Header.SupModuleList)], + ] + NodeList = [['ModuleType', Header.ModuleType], + ['Path', Header.CombinePath], + ['PcdIsDriver', Header.PcdIsDriver], + ['UefiSpecificationVersion', Header.UefiSpecificationVersion], + ['PiSpecificationVersion', Header.PiSpecificationVersion], + ] + for Item in BootModes: + Tmp = BootModeXml() + NodeList.append(Tmp.ToXml(Item, 'BootMode')) + for Item in Events: + Tmp = EventXml() + NodeList.append(Tmp.ToXml(Item, 'Event')) + for Item in Hobs: + Tmp = HobXml() + NodeList.append(Tmp.ToXml(Item, 'Hob')) + Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) + + return Root + + def __str__(self): + Str = "ModuleType = %s Path = %s PcdIsDriver = %s UefiSpecificationVersion = %s PiSpecificationVersion = %s Specification = %s SpecificationVersion = %s %s" \ + % (self.ModuleType, self.Path, self.PcdIsDriver, self.UefiSpecificationVersion, self.PiSpecificationVersion, \ + self.Specification, self.SpecificationVersion, self.CommonDefines) + for Item in self.BootModes: + Str = Str + '\n\t' + str(Item) + for Item in self.Events: + Str = Str + '\n\t' + str(Item) + for Item in self.HOBs: + Str = Str + '\n\t' + str(Item) + return Str + +# SourceFileXml +class SourceFileXml(object): + def __init__(self): + self.SourceFile = '' + self.ToolChainFamily = '' + self.FileType = '' + self.CommonDefines = CommonDefinesXml() + + def FromXml(self, Item, Key): + self.ToolChainFamily = XmlAttribute(Item, 'Family') + self.FileType = XmlAttribute(Item, 'FileType') + self.SourceFile = XmlElement(Item, 'Filename') + self.CommonDefines.FromXml(Item, Key) + + SourceFile = ModuleSourceFileClass() + SourceFile.SourceFile = self.SourceFile + SourceFile.FileType = self.FileType + SourceFile.ToolChainFamily = self.ToolChainFamily + SourceFile.SupArchList = self.CommonDefines.SupArchList + SourceFile.FeatureFlag = self.CommonDefines.FeatureFlag + + return SourceFile + + def ToXml(self, SourceFile, Key): + AttributeList = [['SupArchList', GetStringOfList(SourceFile.SupArchList)], + ['Family', SourceFile.ToolChainFamily], + ['FileType', SourceFile.FileType], + ['FeatureFlag', SourceFile.FeatureFlag], + ] + Root = CreateXmlElement('%s' % Key, SourceFile.SourceFile, [], AttributeList) + + return Root + +# FilenameXml +class FilenameXml(object): + def __init__(self): + self.OS = '' + self.Family = '' + self.FileType = '' + self.Filename = '' + self.Executable = '' + self.CommonDefines = CommonDefinesXml() + + def FromXml(self, Item, Key): + self.OS = XmlAttribute(Item, 'OS') + self.Family = XmlAttribute(Item, 'Family') + self.FileType = XmlAttribute(Item, 'FileType') + self.Filename = XmlElement(Item, 'Filename') + self.Executable = XmlElement(Item, 'Executable') + self.CommonDefines.FromXml(Item, Key) + + Filename = FileClass() + Filename.Family = self.Family + Filename.FileType = self.FileType + Filename.Filename = self.Filename + Filename.Executable = self.Executable + Filename.SupArchList = self.CommonDefines.SupArchList + Filename.FeatureFlag = self.CommonDefines.FeatureFlag + + return Filename + + def ToXml(self, Filename, Key): + AttributeList = [['SupArchList', GetStringOfList(Filename.SupArchList)], + ['Family', Filename.Family], + ['FileType', Filename.FileType], + ['Executable', Filename.Executable], + ['FeatureFlag', Filename.FeatureFlag], + ] + NodeList = [['Filename', Filename.Filename], + ] + Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) + + return Root + + def __str__(self): + return "OS = %s Family = %s FileType = %s Filename = %s Executable = %s %s" \ + % (self.OS, self.Family, self.FileType, self.Filename, self.Executable, self.CommonDefines) + +class BinaryFileXml(object): + def __init__(self): + self.Filenames = [] + self.PatchPcdValues = [] + self.PcdExValues = [] + self.LibraryInstances = [] + self.BuildFlags = [] + + def FromXml(self, Item, Key): + BinaryFile = ModuleBinaryFileClass() + for SubItem in XmlList(Item, '%s/Filename' % Key): + A = FilenameXml() + B = A.FromXml(SubItem, 'Filename') + BinaryFile.Filenames.append(B) + for SubItem in XmlList(Item, '%s/AsBuilt/PatchPcdValue' % Key): + A = PcdEntryXml() + B = A.FromXml(SubItem, 'PatchPcdValue') + BinaryFile.PatchPcdValues.append(B) + for SubItem in XmlList(Item, '%s/AsBuilt/PcdExValue' % Key): + A = PcdEntryXml() + B = A.FromXml(SubItem, 'PcdExValue') + BinaryFile.PatchPcdValues.append(B) + for SubItem in XmlList(Item, '%s/AsBuilt/LibraryInstances/GUID' % Key): + GUID = XmlElement(SubItem, 'GUID') + Version = XmlAttribute(XmlNode(SubItem, 'GUID'), 'Version') + BinaryFile.LibraryInstances.append([GUID, Version]) + for SubItem in XmlList(Item, '%s/AsBuilt/BuildFlags' % Key): + BinaryFile.BuildFlags.append(XmlElement(SubItem, 'BuildFlags')) + + return BinaryFile + + def ToXml(self, BinaryFile, Key): + NodeList = [] + for Item in BinaryFile.Filenames: + Tmp = FilenameXml() + NodeList.append(Tmp.ToXml(Item, 'Filename')) + AsBuiltNodeList = [] + for Item in BinaryFile.PatchPcdValues: + Tmp = PcdEntryXml() + AsBuiltNodeList.append(Tmp.ToXml(Item, 'PatchPcdValue')) + for Item in BinaryFile.PcdExValues: + Tmp = PcdEntryXml() + AsBuiltNodeList.append(Tmp.ToXml(Item, 'PcdExValue')) + LibNodeList = [] + for Item in BinaryFile.LibraryInstances: + LibNode = CreateXmlElement('GUID', Item[0], [], [['Version', Item[1]]]) + LibNodeList.append(LibNode) + if LibNodeList: + AsBuiltNodeList.append(CreateXmlElement('LibraryInstances', '', LibNodeList, [])) + for Item in BinaryFile.BuildFlags: + AsBuiltNodeList.append(CreateXmlElement('BuildFlags', Item, [], [])) + Element = CreateXmlElement('AsBuilt', '', AsBuiltNodeList, []) + NodeList.append(Element) + + Root = CreateXmlElement('%s' % Key, '', NodeList, []) + + return Root + + def __str__(self): + Str = "BinaryFiles:" + for Item in self.Filenames: + Str = Str + '\n\t' + str(Item) + for Item in self.PatchPcdValues: + Str = Str + '\n\t' + str(Item) + for Item in self.PcdExValues: + Str = Str + '\n\t' + str(Item) + for Item in self.LibraryInstances: + Str = Str + '\n\t' + str(Item) + for Item in self.BuildFlags: + Str = Str + '\n\t' + str(Item) + return Str + +# PackageXml +class PackageXml(object): + def __init__(self): + self.Description = '' + self.Guid = '' + self.Version = '' + self.CommonDefines = CommonDefinesXml() + + def FromXml(self, Item, Key): + self.Description = XmlElement(Item, '%s/Description' % Key) + self.Guid = XmlElement(Item, '%s/GUID' % Key) + self.Version = XmlAttribute(XmlNode(Item, '%s/GUID' % Key), 'Version') + self.CommonDefines.FromXml(XmlNode(Item, '%s' % Key), Key) + + PackageDependency = ModulePackageDependencyClass() + PackageDependency.FilePath = self.Description + PackageDependency.PackageGuid = self.Guid + PackageDependency.PackageVersion = self.Version + PackageDependency.FeatureFlag = self.CommonDefines.FeatureFlag + PackageDependency.SupArchList = self.CommonDefines.SupArchList + + return PackageDependency + + def ToXml(self, PackageDependency, Key): + AttributeList = [['SupArchList', GetStringOfList(PackageDependency.SupArchList)], + ['FeatureFlag', PackageDependency.FeatureFlag], + ] + Element1 = CreateXmlElement('GUID', PackageDependency.PackageGuid, [], [['Version', PackageDependency.PackageVersion]]) + NodeList = [['Description', PackageDependency.FilePath], + Element1, + ] + + Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) + + return Root + + def __str__(self): + Str = "Description = %s Guid = %s Version = %s %s" \ + % (self.Description, self.Guid, self.Version, self.CommonDefines) + return Str + +# ExternXml +class ExternXml(object): + def __init__(self): + self.CommonDefines = CommonDefinesXml() + self.EntryPoint = '' + self.UnloadImage = '' + self.Constructor = '' + self.Destructor = '' + self.HelpText = [] + + def FromXml(self, Item, Key): + self.CommonDefines.FromXml(Item, Key) + self.EntryPoint = XmlElement(Item, '%s/EntryPoint' % Key) + self.UnloadImage = XmlElement(Item, '%s/UnloadImage' % Key) + self.Constructor = XmlElement(Item, '%s/Constructor' % Key) + self.Destructor = XmlElement(Item, '%s/Destructor' % Key) + for HelpTextItem in XmlList(Item, '%s/HelpText' % Key): + HelpTextObj = HelpTextXml() + HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key) + self.HelpText.append(HelpTextObj) + + Extern = ModuleExternClass() + Extern.EntryPoint = self.EntryPoint + Extern.UnloadImage = self.UnloadImage + Extern.Constructor = self.Constructor + Extern.Destructor = self.Destructor + Extern.SupArchList = self.CommonDefines.SupArchList + Extern.FeatureFlag = self.CommonDefines.FeatureFlag + Extern.HelpTextList = GetHelpTextList(self.HelpText) + + return Extern + + def ToXml(self, Extern, Key): + AttributeList = [['SupArchList', GetStringOfList(Extern.SupArchList)], + ['FeatureFlag', Extern.FeatureFlag], + ] + NodeList = [['EntryPoint', Extern.EntryPoint], + ['UnloadImage', Extern.UnloadImage], + ['Constructor', Extern.Constructor], + ['Destructor', Extern.Destructor], + ] + for Item in Extern.HelpTextList: + Tmp = HelpTextXml() + NodeList.append(Tmp.ToXml(Item, 'HelpText')) + + Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) + + return Root + + def __str__(self): + Str = "EntryPoint = %s UnloadImage = %s Constructor = %s Destructor = %s %s" \ + % (self.EntryPoint, self.UnloadImage, self.Constructor, self.Destructor, self.CommonDefines) + for Item in self.HelpText: + Str = Str + '\n\t' + str(Item) + return Str +# DepexXml +class DepexXml(object): + def __init__(self): + self.Expression = '' + #self.HelpText = HelpTextXml() + self.HelpText = [] + + def FromXml(self, Item, Key): + self.Expression = XmlElement(Item, '%s/Expression' % Key) + for HelpTextItem in XmlList(Item, '%s/HelpText' % Key): + HelpTextObj = HelpTextXml() + HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key) + self.HelpText.append(HelpTextObj) + + Depex = ModuleDepexClass() + Depex.Depex = self.Expression + Depex.HelpTextList = GetHelpTextList(self.HelpText) + + return Depex + + def ToXml(self, Depex, Key): + AttributeList = [] + NodeList = [['Expression', Depex.Depex], + ] + for Item in Depex.HelpTextList: + Tmp = HelpTextXml() + NodeList.append(Tmp.ToXml(Item, 'HelpText')) + + Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList) + + return Root + + def __str__(self): + Str = "Expression = %s" % (self.Expression) + for Item in self.HelpText: + Str = Str + '\n\t' + str(Item) + return Str + +# PackageSurfaceAreaXml +class PackageSurfaceAreaXml(object): + def __init__(self): + self.Package = None + + def FromXml(self, Item, Key): + # Create a package object + Package = PackageClass() + + # Header + Tmp = PackageHeaderXml() + PackageHeader = Tmp.FromXml(XmlNode(Item, '/PackageSurfaceArea/Header'), 'Header') + Package.PackageHeader = PackageHeader + + # ClonedFrom + Tmp = ClonedFromXml() + ClonedFrom = Tmp.FromXml(XmlNode(Item, '/PackageSurfaceArea/ClonedFrom'), 'ClonedFrom') + if ClonedFrom: + Package.PackageHeader.ClonedFrom.append(ClonedFrom) + + # LibraryClass + for SubItem in XmlList(Item, '/PackageSurfaceArea/LibraryClassDeclarations/LibraryClass'): + Tmp = LibraryClassXml() + LibraryClass = Tmp.FromXml(SubItem, 'LibraryClass') + Package.LibraryClassDeclarations.append(LibraryClass) + + # IndustryStandardHeader + for SubItem in XmlList(Item, '/PackageSurfaceArea/IndustryStandardIncludes/IndustryStandardHeader'): + Tmp = IndustryStandardHeaderXml() + Include = Tmp.FromXml(SubItem, 'IndustryStandardHeader') + Package.IndustryStdHeaders.append(Include) + + # PackageHeader + for SubItem in XmlList(Item, '/PackageSurfaceArea/PackageIncludes/PackageHeader'): + Tmp = PackageIncludeHeaderXml() + Include = Tmp.FromXml(SubItem, 'PackageHeader') + Package.PackageIncludePkgHeaders.append(Include) + + # Guid + for SubItem in XmlList(Item, '/PackageSurfaceArea/GuidDeclarations/Entry'): + Tmp = GuidProtocolPpiXml() + GuidProtocolPpi = Tmp.FromXml(SubItem, 'Entry') + Package.GuidDeclarations.append(GuidProtocolPpi) + + # Protocol + for SubItem in XmlList(Item, '/PackageSurfaceArea/ProtocolDeclarations/Entry'): + Tmp = GuidProtocolPpiXml() + GuidProtocolPpi = Tmp.FromXml(SubItem, 'Entry') + Package.ProtocolDeclarations.append(GuidProtocolPpi) + + # Ppi + for SubItem in XmlList(Item, '/PackageSurfaceArea/PpiDeclarations/Entry'): + Tmp = GuidProtocolPpiXml() + GuidProtocolPpi = Tmp.FromXml(SubItem, 'Entry') + Package.PpiDeclarations.append(GuidProtocolPpi) + + # PcdEntry + for SubItem in XmlList(Item, '/PackageSurfaceArea/PcdDeclarations/PcdEntry'): + Tmp = PcdEntryXml() + PcdEntry = Tmp.FromXml(SubItem, 'PcdEntry') + Package.PcdDeclarations.append(PcdEntry) + + # PcdCheck + for SubItem in XmlList(Item, '/PackageSurfaceArea/PcdRelationshipChecks/PcdCheck'): + Tmp = PcdCheckXml() + PcdCheck = Tmp.FromXml(SubItem, 'PcdCheck') + Package.PcdChecks.append(PcdCheck) + + # MiscellaneousFile + Tmp = MiscellaneousFileXml() + Package.MiscFiles = Tmp.FromXml(XmlNode(Item, '/PackageSurfaceArea/MiscellaneousFiles'), 'MiscellaneousFiles') + + # UserExtensions + Tmp = UserExtensionsXml() + Package.UserExtensions = Tmp.FromXml(XmlNode(Item, '/PackageSurfaceArea/UserExtensions'), 'UserExtensions') + + # Modules + for SubItem in XmlList(Item, '/PackageSurfaceArea/Modules/ModuleSurfaceArea'): + Tmp = ModuleSurfaceAreaXml() + Module = Tmp.FromXml(SubItem, 'ModuleSurfaceArea') + Package.Modules[(Module.ModuleHeader.Guid, Module.ModuleHeader.Version, Module.ModuleHeader.CombinePath)] = Module + + self.Package = Package + return self.Package + + def ToXml(self, Package): + # Create PackageSurfaceArea node + DomPackage = minidom.Document().createElement('PackageSurfaceArea') + + # Header + Tmp = PackageHeaderXml() + DomPackage.appendChild(Tmp.ToXml(Package.PackageHeader, 'Header')) + + # ClonedFrom + Tmp = ClonedFromXml() + if Package.PackageHeader.ClonedFrom != []: + DomPackage.appendChild(Tmp.ToXml(Package.PackageHeader.ClonedFrom[0], 'ClonedFrom')) + + # LibraryClass + LibraryClassNode = CreateXmlElement('LibraryClassDeclarations', '', [], []) + for LibraryClass in Package.LibraryClassDeclarations: + Tmp = LibraryClassXml() + LibraryClassNode.appendChild(Tmp.ToXml(LibraryClass, 'LibraryClass')) + DomPackage.appendChild(LibraryClassNode) + + # IndustryStandardHeader + IndustryStandardHeaderNode = CreateXmlElement('IndustryStandardIncludes', '', [], []) + for Include in Package.IndustryStdHeaders: + Tmp = IndustryStandardHeaderXml() + IndustryStandardHeaderNode.appendChild(Tmp.ToXml(Include, 'IndustryStandardHeader')) + DomPackage.appendChild(IndustryStandardHeaderNode) + + # PackageHeader + PackageIncludeHeaderNode = CreateXmlElement('PackageIncludes', '', [], []) + for Include in Package.PackageIncludePkgHeaders: + Tmp = PackageIncludeHeaderXml() + PackageIncludeHeaderNode.appendChild(Tmp.ToXml(Include, 'PackageHeader')) + DomPackage.appendChild(PackageIncludeHeaderNode) + + # Guid + GuidProtocolPpiNode = CreateXmlElement('GuidDeclarations', '', [], []) + for GuidProtocolPpi in Package.GuidDeclarations: + Tmp = GuidProtocolPpiXml() + GuidProtocolPpiNode.appendChild(Tmp.ToXml(GuidProtocolPpi, 'Entry')) + DomPackage.appendChild(GuidProtocolPpiNode) + + # Protocol + GuidProtocolPpiNode = CreateXmlElement('ProtocolDeclarations', '', [], []) + for GuidProtocolPpi in Package.ProtocolDeclarations: + Tmp = GuidProtocolPpiXml() + GuidProtocolPpiNode.appendChild(Tmp.ToXml(GuidProtocolPpi, 'Entry')) + DomPackage.appendChild(GuidProtocolPpiNode) + + # Ppi + GuidProtocolPpiNode = CreateXmlElement('PpiDeclarations', '', [], []) + for GuidProtocolPpi in Package.PpiDeclarations: + Tmp = GuidProtocolPpiXml() + GuidProtocolPpiNode.appendChild(Tmp.ToXml(GuidProtocolPpi, 'Entry')) + DomPackage.appendChild(GuidProtocolPpiNode) + + # PcdEntry + PcdEntryNode = CreateXmlElement('PcdDeclarations', '', [], []) + for PcdEntry in Package.PcdDeclarations: + Tmp = PcdEntryXml() + PcdEntryNode.appendChild(Tmp.ToXml(PcdEntry, 'PcdEntry')) + DomPackage.appendChild(PcdEntryNode) + + # PcdCheck + PcdCheckNode = CreateXmlElement('PcdRelationshipChecks', '', [], []) + for PcdCheck in Package.PcdChecks: + Tmp = PcdCheckXml() + PcdCheckNode.appendChild(Tmp.ToXml(PcdCheck, 'PcdCheck')) + DomPackage.appendChild(PcdCheckNode) + + # MiscellaneousFile + Tmp = MiscellaneousFileXml() + DomPackage.appendChild(Tmp.ToXml(Package.MiscFiles, 'MiscellaneousFiles')) + + # UserExtensions + Tmp = UserExtensionsXml() + DomPackage.appendChild(Tmp.ToXml(Package.UserExtensions, 'UserExtensions')) + + # Modules + ModuleNode = CreateXmlElement('Modules', '', [], []) + for Module in Package.Modules.values(): + Tmp = ModuleSurfaceAreaXml() + ModuleNode.appendChild(Tmp.ToXml(Module)) + DomPackage.appendChild(ModuleNode) + + return DomPackage + +# ModuleXml +class ModuleSurfaceAreaXml(object): + def __init__(self): + self.Module = None + + def FromXml(self, Item, Key): + # Create a package object + Module = ModuleClass() + + # Header + Tmp = HeaderXml() + ModuleHeader = Tmp.FromXml(XmlNode(Item, '/ModuleSurfaceArea/Header'), 'Header') + Module.ModuleHeader = ModuleHeader + + # ModuleProperties + Tmp = ModulePropertyXml() + (Header, BootModes, Events, HOBs) = Tmp.FromXml(XmlNode(Item, '/ModuleSurfaceArea/ModuleProperties'), 'ModuleProperties', ModuleHeader) + Module.ModuleHeader = Header + Module.BootModes = BootModes + Module.Events = Events + Module.Hobs = HOBs + + # ClonedFrom + Tmp = ClonedFromXml() + ClonedFrom = Tmp.FromXml(XmlNode(Item, '/ModuleSurfaceArea/ClonedFrom'), 'ClonedFrom') + if ClonedFrom: + Module.ModuleHeader.ClonedFrom.append(ClonedFrom) + + # LibraryClass + #LibraryClassNode = CreateXmlElement('LibraryClassDefinitions', '', [], []) + for SubItem in XmlList(Item, '/ModuleSurfaceArea/LibraryClassDefinitions/LibraryClass'): + Tmp = LibraryClassXml() + LibraryClass = Tmp.FromXml(SubItem, 'LibraryClass') + Module.LibraryClasses.append(LibraryClass) + + # SourceFile + #SourceFileNode = CreateXmlElement('SourceFiles', '', [], []) + for SubItem in XmlList(Item, '/ModuleSurfaceArea/SourceFiles/Filename'): + Tmp = SourceFileXml() + SourceFile = Tmp.FromXml(SubItem, 'Filename') + Module.Sources.append(SourceFile) + + # BinaryFile + #BinaryFileNode = CreateXmlElement('BinaryFiles', '', [], []) + for SubItem in XmlList(Item, '/ModuleSurfaceArea/BinaryFiles/BinaryFile'): + Tmp = BinaryFileXml() + BinaryFile = Tmp.FromXml(SubItem, 'BinaryFile') + Module.Binaries.append(BinaryFile) + + # PackageDependencies + #PackageDependencyNode = CreateXmlElement('PackageDependencies', '', [], []) + for SubItem in XmlList(Item, '/ModuleSurfaceArea/PackageDependencies/Package'): + Tmp = PackageXml() + PackageDependency = Tmp.FromXml(SubItem, 'Package') + Module.PackageDependencies.append(PackageDependency) + + # Guid + #GuidProtocolPpiNode = CreateXmlElement('Guids', '', [], []) + for SubItem in XmlList(Item, '/ModuleSurfaceArea/Guids/GuidCName'): + Tmp = GuidProtocolPpiXml() + GuidProtocolPpi = Tmp.FromXml(SubItem, 'GuidCName') + Module.Guids.append(GuidProtocolPpi) + + # Protocol + #GuidProtocolPpiNode = CreateXmlElement('Protocols', '', [], []) + for SubItem in XmlList(Item, '/ModuleSurfaceArea/Protocols/Protocol'): + Tmp = GuidProtocolPpiXml() + GuidProtocolPpi = Tmp.FromXml(SubItem, 'Protocol') + Module.Protocols.append(GuidProtocolPpi) + + # Ppi + #GuidProtocolPpiNode = CreateXmlElement('PPIs', '', [], []) + for SubItem in XmlList(Item, '/ModuleSurfaceArea/PPIs/Ppi'): + Tmp = GuidProtocolPpiXml() + GuidProtocolPpi = Tmp.FromXml(SubItem, 'Ppi') + Module.Ppis.append(GuidProtocolPpi) + + # Extern + #ExternNode = CreateXmlElement('Externs', '', [], []) + for SubItem in XmlList(Item, '/ModuleSurfaceArea/Externs/Extern'): + Tmp = ExternXml() + Extern = Tmp.FromXml(SubItem, 'Extern') + Module.Externs.append(Extern) + + # PcdCoded + #PcdEntryNode = CreateXmlElement('PcdCoded', '', [], []) + for SubItem in XmlList(Item, '/ModuleSurfaceArea/PcdCoded/PcdEntry'): + Tmp = PcdEntryXml() + PcdEntry = Tmp.FromXml(SubItem, 'PcdEntry') + Module.PcdCodes.append(PcdEntry) + + # PeiDepex + #DepexNode = CreateXmlElement('PeiDepex', '', [], []) + Tmp = DepexXml() + Module.PeiDepex = Tmp.FromXml(XmlNode(Item, '/ModuleSurfaceArea/PeiDepex'), 'PeiDepex') + + # DxeDepex + #DepexNode = CreateXmlElement('DxeDepex', '', [], []) + Tmp = DepexXml() + Module.DxeDepex = Tmp.FromXml(XmlNode(Item, '/ModuleSurfaceArea/DxeDepex'), 'DxeDepex') + + # SmmDepex + #DepexNode = CreateXmlElement('SmmDepex', '', [], []) + Tmp = DepexXml() + Module.SmmDepex = Tmp.FromXml(XmlNode(Item, '/ModuleSurfaceArea/DxeDepex'), 'SmmDepex') + + # MiscellaneousFile + Tmp = MiscellaneousFileXml() + Module.MiscFiles = Tmp.FromXml(XmlNode(Item, '/ModuleSurfaceArea/MiscellaneousFiles'), 'MiscellaneousFiles') + + # UserExtensions + Tmp = UserExtensionsXml() + Module.UserExtensions = Tmp.FromXml(XmlNode(Item, '/ModuleSurfaceArea/UserExtensions'), 'UserExtensions') + + # return the module object + self.Module = Module + return self.Module + + def ToXml(self, Module): + # Create root node of module surface area + DomModule = minidom.Document().createElement('ModuleSurfaceArea') + + # Header + Tmp = HeaderXml() + DomModule.appendChild(Tmp.ToXml(Module.ModuleHeader, 'Header')) + + # ModuleProperties + Tmp = ModulePropertyXml() + DomModule.appendChild(Tmp.ToXml(Module.ModuleHeader, Module.BootModes, Module.Events, Module.Hobs, 'ModuleProperties')) + + # ClonedFrom + Tmp = ClonedFromXml() + if Module.ModuleHeader.ClonedFrom != []: + DomModule.appendChild(Tmp.ToXml(Module.ModuleHeader.ClonedFrom[0], 'ClonedFrom')) + + # LibraryClass + LibraryClassNode = CreateXmlElement('LibraryClassDefinitions', '', [], []) + for LibraryClass in Module.LibraryClasses: + Tmp = LibraryClassXml() + LibraryClassNode.appendChild(Tmp.ToXml(LibraryClass, 'LibraryClass')) + DomModule.appendChild(LibraryClassNode) + + # SourceFile + SourceFileNode = CreateXmlElement('SourceFiles', '', [], []) + for SourceFile in Module.Sources: + Tmp = SourceFileXml() + SourceFileNode.appendChild(Tmp.ToXml(SourceFile, 'Filename')) + DomModule.appendChild(SourceFileNode) + + # BinaryFile + BinaryFileNode = CreateXmlElement('BinaryFiles', '', [], []) + for BinaryFile in Module.Binaries: + Tmp = BinaryFileXml() + BinaryFileNode.appendChild(Tmp.ToXml(BinaryFile, 'BinaryFile')) + DomModule.appendChild(BinaryFileNode) + + # PackageDependencies + PackageDependencyNode = CreateXmlElement('PackageDependencies', '', [], []) + for PackageDependency in Module.PackageDependencies: + Tmp = PackageXml() + PackageDependencyNode.appendChild(Tmp.ToXml(PackageDependency, 'Package')) + DomModule.appendChild(PackageDependencyNode) + + # Guid + GuidProtocolPpiNode = CreateXmlElement('Guids', '', [], []) + for GuidProtocolPpi in Module.Guids: + Tmp = GuidProtocolPpiXml() + GuidProtocolPpiNode.appendChild(Tmp.ToXml(GuidProtocolPpi, 'GuidCName')) + DomModule.appendChild(GuidProtocolPpiNode) + + # Protocol + GuidProtocolPpiNode = CreateXmlElement('Protocols', '', [], []) + for GuidProtocolPpi in Module.Protocols: + Tmp = GuidProtocolPpiXml() + GuidProtocolPpiNode.appendChild(Tmp.ToXml(GuidProtocolPpi, 'Protocol')) + DomModule.appendChild(GuidProtocolPpiNode) + + # Ppi + GuidProtocolPpiNode = CreateXmlElement('PPIs', '', [], []) + for GuidProtocolPpi in Module.Ppis: + Tmp = GuidProtocolPpiXml() + GuidProtocolPpiNode.appendChild(Tmp.ToXml(GuidProtocolPpi, 'Ppi')) + DomModule.appendChild(GuidProtocolPpiNode) + + # Extern + ExternNode = CreateXmlElement('Externs', '', [], []) + for Extern in Module.Externs: + Tmp = ExternXml() + ExternNode.appendChild(Tmp.ToXml(Extern, 'Extern')) + DomModule.appendChild(ExternNode) + + # PcdCoded + PcdEntryNode = CreateXmlElement('PcdCoded', '', [], []) + for PcdEntry in Module.PcdCodes: + Tmp = PcdEntryXml() + PcdEntryNode.appendChild(Tmp.ToXml(PcdEntry, 'PcdEntry')) + DomModule.appendChild(PcdEntryNode) + + # PeiDepex + if Module.PeiDepex: + DepexNode = CreateXmlElement('PeiDepex', '', [], []) + Tmp = DepexXml() + DomModule.appendChild(Tmp.ToXml(Module.PeiDepex, 'PeiDepex')) + + # DxeDepex + if Module.DxeDepex: + DepexNode = CreateXmlElement('DxeDepex', '', [], []) + Tmp = DepexXml() + DomModule.appendChild(Tmp.ToXml(Module.DxeDepex, 'DxeDepex')) + + # SmmDepex + if Module.SmmDepex: + DepexNode = CreateXmlElement('SmmDepex', '', [], []) + Tmp = DepexXml() + DomModule.appendChild(Tmp.ToXml(Module.SmmDepex, 'SmmDepex')) + + # MiscellaneousFile + Tmp = MiscellaneousFileXml() + DomModule.appendChild(Tmp.ToXml(Module.MiscFiles, 'MiscellaneousFiles')) + + # UserExtensions + Tmp = UserExtensionsXml() + DomModule.appendChild(Tmp.ToXml(Module.UserExtensions, 'UserExtensions')) + + return DomModule + +# DistributionPackageXml +class DistributionPackageXml(object): + def __init__(self): + self.Dp = DistributionPackageClass() + + def FromXml(self, Filename = None): + if Filename != None: + self.Dp = DistributionPackageClass() + + # Load to XML + self.Pkg = XmlParseFile(Filename) + + # Parse Header information + Tmp = DistributionPackageHeaderXml() + DistributionPackageHeader = Tmp.FromXml(XmlNode(self.Pkg, '/DistributionPackage/DistributionHeader'), 'DistributionHeader') + self.Dp.Header = DistributionPackageHeader + + # Parse each PackageSurfaceArea + for Item in XmlList(self.Pkg, '/DistributionPackage/PackageSurfaceArea'): + Psa = PackageSurfaceAreaXml() + Package = Psa.FromXml(Item, 'PackageSurfaceArea') + self.Dp.PackageSurfaceArea[(Package.PackageHeader.Guid, Package.PackageHeader.Version, Package.PackageHeader.CombinePath)] = Package + + # Parse each ModuleSurfaceArea + for Item in XmlList(self.Pkg, '/DistributionPackage/ModuleSurfaceArea'): + Msa = ModuleSurfaceAreaXml() + Module = Msa.FromXml(Item, 'ModuleSurfaceArea') + self.Dp.ModuleSurfaceArea[(Module.ModuleHeader.Guid, Module.ModuleHeader.Version, Module.ModuleHeader.CombinePath)] = Module + + # Parse Tools + Tmp = MiscellaneousFileXml() + self.Dp.Tools = Tmp.FromXml2(XmlNode(self.Pkg, '/DistributionPackage/Tools'), 'Tools') + + # Parse MiscFiles + Tmp = MiscellaneousFileXml() + self.Dp.MiscellaneousFiles = Tmp.FromXml2(XmlNode(self.Pkg, '/DistributionPackage/MiscellaneousFiles'), 'MiscellaneousFiles') + + return self.Dp + + def ToXml(self, Dp): + if Dp != None: + # Parse DistributionPackageHeader + Attrs = [['xmlns', 'http://www.uefi.org/2008/2.1'], + ['xmlns:xsi', 'http:/www.w3.org/2001/XMLSchema-instance'], + ] + Root = CreateXmlElement('DistributionPackage', '', [], Attrs) + + Tmp = DistributionPackageHeaderXml() + Root.appendChild(Tmp.ToXml(Dp.Header, 'DistributionHeader')) + + # Parse each PackageSurfaceArea + for Package in Dp.PackageSurfaceArea.values(): + Psa = PackageSurfaceAreaXml() + DomPackage = Psa.ToXml(Package) + Root.appendChild(DomPackage) + + # Parse each ModuleSurfaceArea + for Module in Dp.ModuleSurfaceArea.values(): + Msa = ModuleSurfaceAreaXml() + DomModule = Msa.ToXml(Module) + Root.appendChild(DomModule) + + # Parse Tools + Tmp = MiscellaneousFileXml() + #Tools = Tmp.FromXml2(XmlNode(self.Pkg, '/DistributionPackage/Tools'), 'Tools') + Root.appendChild(Tmp.ToXml2(Dp.Tools, 'Tools')) + + # Parse MiscFiles + Tmp = MiscellaneousFileXml() + #Tools = Tmp.FromXml2(XmlNode(self.Pkg, '/DistributionPackage/MiscellaneousFiles'), 'MiscellaneousFiles') + Root.appendChild(Tmp.ToXml2(Dp.MiscellaneousFiles, 'MiscellaneousFiles')) + + return Root.toprettyxml(indent = ' ') + + return '' + +if __name__ == '__main__': + M = DistributionPackageXml() + M.FromXml('C:\Test.xml') + print M.ToXml(M.Dp) + \ No newline at end of file diff --git a/BaseTools/Source/Python/Common/XmlRoutines.py b/BaseTools/Source/Python/Common/XmlRoutines.py new file mode 100644 index 0000000000..e5fedae83d --- /dev/null +++ b/BaseTools/Source/Python/Common/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) 2007, 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 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 xml.dom.minidom + +## Create a element of XML +# +# @param Name +# @param String +# @param NodeList +# @param AttributeList +# +# @revel Element +# +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. +# +# @revel Nodes A list of XML nodes matching XPath style Sting. +# +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. +# +# @revel Node A single XML node matching XPath style Sting. +# +def XmlNode(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('/') + 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 "" + + +## 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. +# +# @revel Element An XML element matching XPath style Sting. +# +def XmlElement(Dom, String): + try: + return XmlNode(Dom, String).firstChild.data.strip() + except: + 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. +# +# @revel Element An XML element in current root Dom. +# +def XmlElementData(Dom): + try: + return Dom.firstChild.data.strip() + except: + 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. +# +# @revel Elements A list of XML elements matching XPath style Sting. +# +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. +# +# @revel Element A single XML element matching XPath style Sting. +# +def XmlAttribute(Dom, Attribute): + try: + return Dom.getAttribute(Attribute).strip() + except: + 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. +# +# @revel Element A single XML element matching XPath style Sting. +# +def XmlNodeName(Dom): + try: + return Dom.nodeName.strip() + except: + 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. +# +# @revel Dom The Dom object achieved from the XML file. +# +def XmlParseFile(FileName): + try: + XmlFile = open(FileName) + Dom = xml.dom.minidom.parse(XmlFile) + XmlFile.close() + return Dom + except Exception, X: + print X + return "" + +# This acts like the main() function for the script, unless it is 'import'ed +# into another script. +if __name__ == '__main__': + # Nothing to do here. Could do some unit tests. + A = CreateXmlElement('AAA', 'CCC', [['AAA', '111'], ['BBB', '222']], [['A', '1'], ['B', '2']]) + B = CreateXmlElement('ZZZ', 'CCC', [['XXX', '111'], ['YYY', '222']], [['A', '1'], ['B', '2']]) + C = CreateXmlList('DDD', 'EEE', [A, B], ['FFF', 'GGG']) + print C.toprettyxml(indent = " ") + pass diff --git a/BaseTools/Source/Python/Common/__init__.py b/BaseTools/Source/Python/Common/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/BaseTools/Source/Python/CommonDataClass/CommonClass.py b/BaseTools/Source/Python/CommonDataClass/CommonClass.py new file mode 100644 index 0000000000..763550fe47 --- /dev/null +++ b/BaseTools/Source/Python/CommonDataClass/CommonClass.py @@ -0,0 +1,473 @@ +## @file +# This file is used to define common items of class object +# +# Copyright (c) 2007, 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 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. + + +# +# Generate help text +# +def GenerateHelpText(Text, Lang): + if Text: + Ht = HelpTextClass() + Ht.Lang = Lang + Ht.String = Text + + return Ht + + return None + +## CommonClass +# +# This class defined common items 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 '' +# +# @var Usage: To store value for Usage, selection scope is in below list +# ALWAYS_CONSUMED | SOMETIMES_CONSUMED | ALWAYS_PRODUCED | SOMETIMES_PRODUCED | TO_START | BY_START | PRIVATE +# @var FeatureFlag: To store value for FeatureFlag +# @var SupArchList: To store value for SupArchList, selection scope is in below list +# EBC | IA32 | X64 | IPF | ARM | PPC +# @var HelpText: To store value for HelpText +# +class CommonClass(object): + def __init__(self, Usage = None, FeatureFlag = '', SupArchList = None, HelpText = ''): + self.Usage = Usage + if self.Usage == None: + self.Usage = [] + self.FeatureFlag = FeatureFlag + self.SupArchList = SupArchList + if self.SupArchList == None: + self.SupArchList = [] + self.HelpText = HelpText + self.HelpTextList = [] + +## CommonClass +# +# This class defined common items used in Module/Platform/Package files +# +# @param object: Inherited from object class +# +# @var Abstract: To store value for Abstract +# @var Description: To store value for Description +# @var Copyright: To store value for Copyright +# @var License: To store value for License +# @var Specification: To store value for Specification +# +class CommonHeaderClass(object): + def __init__(self): + self.Abstract = '' + self.Description = '' + self.Copyright = '' + self.License = '' + self.Specification = {} + +## HelpTextClass +# +# This class defined HelpText item used in PKG file +# +# @param object: Inherited from object class +# +# @var Lang: To store value for Lang +# @var String: To store value for String +# +class HelpTextClass(object): + def __init__(self): + self.Lang = '' + self.String = '' + +## DefineClass +# +# This class defined item DEFINE used in Module/Platform/Package files +# +# @param object: Inherited from object class +# +# @var Define: To store value for Define, it is a set structure as +# { (DefineName, Arch) : DefineValue, ... } +# +class DefineClass(object): + def __init__(self): + self.Define = {} + +## ClonedRecordClass +# +# This class defined ClonedRecord items used in Module/Platform/Package files +# +# @param object: Inherited from object class +# +# @var Id: To store value for Id +# @var FarGuid: To store value for FarGuid +# @var PackageGuid: To store value for PackageGuid +# @var PackageVersion: To store value for PackageVersion +# @var ModuleGuid: To store value for ModuleGuid +# @var ModuleVersion: To store value for ModuleVersion +# +class ClonedRecordClass(object): + def __init__(self): + self.Id = 0 + self.FarGuid = '' + self.PackageGuid = '' + self.PackageVersion = '' + self.ModuleGuid = '' + self.ModuleVersion = '' + +## IdentificationClass +# +# This class defined Identification items used in Module/Platform/Package files +# +# @param object: Inherited from object class +# +# @var Name: To store value for Name +# ModuleName(Inf) / PackageName(Dec) / PlatformName(Dsc) +# @var Guid: To store value for Guid +# @var Version: To store value for Version +# @var FileName: To store value for FileName +# @var FullPath: To store value for FullPath +# +class IdentificationClass(object): + def __init__(self): + self.Name = '' + self.BaseName = '' + self.Guid = '' + self.Version = '' + self.FileName = '' + self.FullPath = '' + self.RelaPath = '' + self.PackagePath = '' + self.ModulePath = '' + self.CombinePath = '' + +## IncludeStatementClass +# +# This class defined IncludeFiles item used in Module/Platform/Package files +# +# @param object: Inherited from object class +# +# @var IncludeFiles: To store value for IncludeFiles +# It is a set structure as { IncludeFile : [Arch1, Arch2, ...], ... } +# +class IncludeStatementClass(object): + def __init__(self): + self.IncludeFiles = {} + +## GuidProtocolPpiCommonClass +# +# This class defined Guid, Protocol and Ppi like items used in Module/Platform/Package files +# +# @param CommonClass: Inherited from CommonClass class +# +# @var Name: To store value for Name +# @var CName: To store value for CName +# @var Guid: To store value for Guid +# @var Notify: To store value for Notify +# @var GuidTypeList: To store value for GuidTypeList, selection scope is in below list +# DATA_HUB_RECORD | EFI_EVENT | EFI_SYSTEM_CONFIGURATION_TABLE | EFI_VARIABLE | GUID | HII_PACKAGE_LIST | HOB | TOKEN_SPACE_GUID +# @var SupModuleList: To store value for SupModuleList, selection scope is in below list +# BASE | SEC | PEI_CORE | PEIM | DXE_CORE | DXE_DRIVER | DXE_RUNTIME_DRIVER | DXE_SAL_DRIVER | DXE_SMM_DRIVER | UEFI_DRIVER | UEFI_APPLICATION | USER_DEFINED +# +class GuidProtocolPpiCommonClass(CommonClass): + def __init__(self): + self.Name = '' + self.CName = '' + self.Guid = '' + self.VariableName = '' + self.Notify = False + self.GuidTypeList = [] + self.GuidTypeLists = [] + self.SupModuleList = [] + CommonClass.__init__(self) + +## LibraryClassClass +# +# This class defined Library item used in Module/Platform/Package files +# +# @param CommonClass: Inherited from CommonClass class +# @param DefineClass: Inherited from DefineClass class +# +# @var LibraryClass: To store value for LibraryClass +# @var IncludeHeader: To store value for IncludeHeader +# @var RecommendedInstanceVersion: To store value for RecommendedInstanceVersion +# @var RecommendedInstanceGuid: To store value for RecommendedInstanceGuid +# @var RecommendedInstance: To store value for RecommendedInstance, selection scope is in below list +# DATA_HUB_RECORD | EFI_EVENT | EFI_SYSTEM_CONFIGURATION_TABLE | EFI_VARIABLE | GUID | HII_PACKAGE_LIST | HOB | TOKEN_SPACE_GUID +# @var SupModuleList: To store value for SupModuleList, selection scope is in below list +# BASE | SEC | PEI_CORE | PEIM | DXE_CORE | DXE_DRIVER | DXE_RUNTIME_DRIVER | DXE_SAL_DRIVER | DXE_SMM_DRIVER | UEFI_DRIVER | UEFI_APPLICATION | USER_DEFINED +# +class LibraryClassClass(CommonClass, DefineClass): + def __init__(self): + self.LibraryClass = '' + self.IncludeHeader = '' + self.RecommendedInstanceVersion = '' + self.RecommendedInstanceGuid = '' + self.RecommendedInstance = '' + self.SupModuleList = [] + CommonClass.__init__(self) + DefineClass.__init__(self) + +## GuidClass +# +# This class defined Guid item used in Module/Platform/Package files +# +# @param GuidProtocolPpiCommonClass: Inherited from GuidProtocolPpiCommonClass class +# +class GuidClass(GuidProtocolPpiCommonClass): + def __init__(self): + GuidProtocolPpiCommonClass.__init__(self) + +## ProtocolClass +# +# This class defined Protocol item used in Module/Platform/Package files +# +# @param GuidProtocolPpiCommonClass: Inherited from GuidProtocolPpiCommonClass class +# +class ProtocolClass(GuidProtocolPpiCommonClass): + def __init__(self): + GuidProtocolPpiCommonClass.__init__(self) + +## PpiClass +# +# This class defined Ppi item used in Module/Platform/Package files +# +# @param GuidProtocolPpiCommonClass: Inherited from GuidProtocolPpiCommonClass class +# +class PpiClass(GuidProtocolPpiCommonClass): + def __init__(self): + GuidProtocolPpiCommonClass.__init__(self) + +## SkuInfoClass +# +# This class defined SkuInfo item used in Module/Platform/Package files +# +# @param object: Inherited from object class +# @param SkuIdName: Input value for SkuIdName, default is '' +# @param SkuId: Input value for SkuId, default is '' +# @param VariableName: Input value for VariableName, default is '' +# @param VariableGuid: Input value for VariableGuid, default is '' +# @param VariableOffset: Input value for VariableOffset, default is '' +# @param HiiDefaultValue: Input value for HiiDefaultValue, default is '' +# @param VpdOffset: Input value for VpdOffset, default is '' +# @param DefaultValue: Input value for DefaultValue, default is '' +# +# @var SkuIdName: To store value for SkuIdName +# @var SkuId: To store value for SkuId +# @var VariableName: To store value for VariableName +# @var VariableGuid: To store value for VariableGuid +# @var VariableOffset: To store value for VariableOffset +# @var HiiDefaultValue: To store value for HiiDefaultValue +# @var VpdOffset: To store value for VpdOffset +# @var DefaultValue: To store value for DefaultValue +# +class SkuInfoClass(object): + def __init__(self, SkuIdName = '', SkuId = '', VariableName = '', VariableGuid = '', VariableOffset = '', + HiiDefaultValue = '', VpdOffset = '', DefaultValue = '', VariableGuidValue = ''): + self.SkuIdName = SkuIdName + self.SkuId = SkuId + + # + # Used by Hii + # + self.VariableName = VariableName + self.VariableGuid = VariableGuid + self.VariableGuidValue = VariableGuidValue + self.VariableOffset = VariableOffset + self.HiiDefaultValue = HiiDefaultValue + + # + # Used by Vpd + # + self.VpdOffset = VpdOffset + + # + # Used by Default + # + self.DefaultValue = DefaultValue + + ## Convert the class to a string + # + # Convert each member of the class to string + # Organize to a signle line format string + # + # @retval Rtn Formatted String + # + def __str__(self): + Rtn = Rtn = 'SkuId = ' + str(self.SkuId) + "," + \ + 'SkuIdName = ' + str(self.SkuIdName) + "," + \ + 'VariableName = ' + str(self.VariableName) + "," + \ + 'VariableGuid = ' + str(self.VariableGuid) + "," + \ + 'VariableOffset = ' + str(self.VariableOffset) + "," + \ + 'HiiDefaultValue = ' + str(self.HiiDefaultValue) + "," + \ + 'VpdOffset = ' + str(self.VpdOffset) + "," + \ + 'DefaultValue = ' + str(self.DefaultValue) + "," + return Rtn +## PcdErrorClass +# +# +# +class PcdErrorClass(object): + def __init__(self): + self.ValidValueList = '' + self.ValidValueListLang = '' + self.ValidValueRange = '' + self.Expression = '' + self.ErrorNumber = '' + self.ErrorMessage = [] + +## PcdClass +# +# This class defined Pcd item used in Module/Platform/Package files +# +# @param CommonClass: Inherited from CommonClass class +# @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 [] +# +# @var CName: To store value for CName +# @var Token: To store value for Token +# @var TokenSpaceGuidCName: To store value for TokenSpaceGuidCName +# @var DatumType: To store value for DatumType, selection scope is in below list +# UINT8 | UINT16 | UINT32 | UINT64 | VOID* | BOOLEAN +# @var MaxDatumSize: To store value for MaxDatumSize +# @var DefaultValue: To store value for DefaultValue +# @var ItemType: To store value for ItemType, selection scope is in below list +# FEATURE_FLAG | FIXED_AT_BUILD | PATCHABLE_IN_MODULE | DYNAMIC | DYNAMIC_EX +# @var ValidUsage: To store value for ValidUsage, selection scope is in below list +# FEATURE_FLAG | FIXED_AT_BUILD | PATCHABLE_IN_MODULE | DYNAMIC | DYNAMIC_EX +# @var SkuInfoList: To store value for SkuInfoList +# It is a set structure as { [SkuIdName] : SkuInfoClass } +# @var SupModuleList: To store value for SupModuleList, selection scope is in below list +# BASE | SEC | PEI_CORE | PEIM | DXE_CORE | DXE_DRIVER | DXE_RUNTIME_DRIVER | DXE_SAL_DRIVER | DXE_SMM_DRIVER | UEFI_DRIVER | UEFI_APPLICATION | USER_DEFINED +# +class PcdClass(CommonClass): + def __init__(self, CName = '', Token = '', TokenSpaceGuidCName = '', DatumType = '', MaxDatumSize = '', DefaultValue = '', ItemType = '', ValidUsage = None, SkuInfoList = None, SupModuleList = None): + self.CName = CName + self.Token = Token + self.TokenSpaceGuidCName = TokenSpaceGuidCName + self.DatumType = DatumType + self.MaxDatumSize = MaxDatumSize + self.DefaultValue = DefaultValue + self.ItemType = ItemType + self.ValidUsage = ValidUsage + self.PcdItemType = '' + self.TokenSpaceGuidValue = '' + self.PcdUsage = '' + self.PcdCName = '' + self.Value = '' + self.Offset = '' + if self.ValidUsage == None: + self.ValidUsage = [] + self.SkuInfoList = SkuInfoList + if self.SkuInfoList == None: + self.SkuInfoList = {} + self.SupModuleList = SupModuleList + if self.SupModuleList == None: + self.SupModuleList = [] + CommonClass.__init__(self) + self.PcdErrors = [] + +## BuildOptionClass +# +# This class defined BuildOption item used in Module/Platform/Package files +# +# @param IncludeStatementClass: Inherited from IncludeStatementClass class +# @param ToolChainFamily: Input value for ToolChainFamily, default is '' +# @param ToolChain: Input value for ToolChain, default is '' +# @param Option: Input value for Option, default is '' +# +# @var Statement: To store value for Statement +# It is a string in a special format as "Family:Target_TagName_Tarch_ToolCode_FLAGS = String" +# @var ToolChainFamily: To store value for ToolChainFamily +# @var ToolChain: To store value for ToolChain +# @var Option: To store value for Option +# @var BuildTarget: To store value for BuildTarget +# @var TagName: To store value for TagName +# @var ToolCode: To store value for ToolCode +# @var SupArchList: To store value for SupArchList, selection scope is in below list +# EBC | IA32 | X64 | IPF | ARM | PPC +# +class BuildOptionClass(IncludeStatementClass): + def __init__(self, ToolChainFamily = '', ToolChain = '', Option = ''): + IncludeStatementClass.__init__(self) + self.Statement = '' + self.ToolChainFamily = ToolChainFamily + self.ToolChain = ToolChain + self.Option = Option + self.BuildTarget = '' + self.TagName = '' + self.ToolCode = '' + self.SupArchList = [] + +## IncludeClass +# +# This class defined Include item used in Module/Platform/Package files +# +# @param CommonClass: Inherited from CommonClass class +# +# @var FilePath: To store value for FilePath +# @var ModuleType: To store value for ModuleType +# @var Comment: To store value for Comment +# +class IncludeClass(CommonClass): + def __init__(self): + self.FilePath = '' + self.ModuleType = '' + self.SupModuleList = [] + self.Comment = '' + CommonClass.__init__(self) + +## FileClass +# +# +class FileClass(CommonClass): + def __init__(self): + self.Filename = '' + self.Executable = '' + self.Family = '' + self.FileType = '' + CommonClass.__init__(self) + + +## MiscFileClass +# +# +class MiscFileClass(CommonHeaderClass): + def __init__(self): + CommonHeaderClass.__init__(self) + self.Name = '' + self.Files = [] + + +## UserExtensionsClass +# +# This class defined UserExtensions item used in Module/Platform/Package files +# +# @param object: Inherited from object class +# +# @var UserID: To store value for UserID +# @var Identifier: To store value for Identifier +# @var Content: To store value for Content +# +class UserExtensionsClass(object): + def __init__(self): + self.UserID = '' + self.Identifier = 0 + self.Content = '' + self.Defines = [] + self.BuildOptions = [] diff --git a/BaseTools/Source/Python/CommonDataClass/DataClass.py b/BaseTools/Source/Python/CommonDataClass/DataClass.py new file mode 100644 index 0000000000..00f4be8332 --- /dev/null +++ b/BaseTools/Source/Python/CommonDataClass/DataClass.py @@ -0,0 +1,351 @@ +## @file +# This file is used to define class for data sturcture used in ECC +# +# Copyright (c) 2008, 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 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 Common.EdkLogger as EdkLogger + +## +# 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_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 + +MODEL_LIST = [('MODEL_UNKNOWN', MODEL_UNKNOWN), + ('MODEL_FILE_C', MODEL_FILE_C), + ('MODEL_FILE_H', MODEL_FILE_H), + ('MODEL_FILE_ASM', MODEL_FILE_ASM), + ('MODEL_FILE_INF', MODEL_FILE_INF), + ('MODEL_FILE_DEC', MODEL_FILE_DEC), + ('MODEL_FILE_DSC', MODEL_FILE_DSC), + ('MODEL_FILE_FDF', MODEL_FILE_FDF), + ('MODEL_FILE_INC', MODEL_FILE_INC), + ('MODEL_IDENTIFIER_FILE_HEADER', MODEL_IDENTIFIER_FILE_HEADER), + ('MODEL_IDENTIFIER_FUNCTION_HEADER', MODEL_IDENTIFIER_FUNCTION_HEADER), + ('MODEL_IDENTIFIER_COMMENT', MODEL_IDENTIFIER_COMMENT), + ('MODEL_IDENTIFIER_PARAMETER', MODEL_IDENTIFIER_PARAMETER), + ('MODEL_IDENTIFIER_STRUCTURE', MODEL_IDENTIFIER_STRUCTURE), + ('MODEL_IDENTIFIER_VARIABLE', MODEL_IDENTIFIER_VARIABLE), + ('MODEL_IDENTIFIER_INCLUDE', MODEL_IDENTIFIER_INCLUDE), + ('MODEL_IDENTIFIER_PREDICATE_EXPRESSION', MODEL_IDENTIFIER_PREDICATE_EXPRESSION), + ('MODEL_IDENTIFIER_ENUMERATE', MODEL_IDENTIFIER_ENUMERATE), + ('MODEL_IDENTIFIER_PCD', MODEL_IDENTIFIER_PCD), + ('MODEL_IDENTIFIER_UNION', MODEL_IDENTIFIER_UNION), + ('MODEL_IDENTIFIER_MACRO_IFDEF', MODEL_IDENTIFIER_MACRO_IFDEF), + ('MODEL_IDENTIFIER_MACRO_IFNDEF', MODEL_IDENTIFIER_MACRO_IFNDEF), + ('MODEL_IDENTIFIER_MACRO_DEFINE', MODEL_IDENTIFIER_MACRO_DEFINE), + ('MODEL_IDENTIFIER_MACRO_ENDIF', MODEL_IDENTIFIER_MACRO_ENDIF), + ('MODEL_IDENTIFIER_MACRO_PROGMA', MODEL_IDENTIFIER_MACRO_PROGMA), + ('MODEL_IDENTIFIER_FUNCTION_CALLING', MODEL_IDENTIFIER_FUNCTION_CALLING), + ('MODEL_IDENTIFIER_TYPEDEF', MODEL_IDENTIFIER_TYPEDEF), + ('MODEL_IDENTIFIER_FUNCTION_DECLARATION', MODEL_IDENTIFIER_FUNCTION_DECLARATION), + ('MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION', MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION), + ('MODEL_EFI_PROTOCOL', MODEL_EFI_PROTOCOL), + ('MODEL_EFI_PPI', MODEL_EFI_PPI), + ('MODEL_EFI_GUID', MODEL_EFI_GUID), + ('MODEL_EFI_LIBRARY_CLASS', MODEL_EFI_LIBRARY_CLASS), + ('MODEL_EFI_LIBRARY_INSTANCE', MODEL_EFI_LIBRARY_INSTANCE), + ('MODEL_EFI_PCD', MODEL_EFI_PCD), + ('MODEL_EFI_SKU_ID', MODEL_EFI_SKU_ID), + ('MODEL_EFI_INCLUDE', MODEL_EFI_INCLUDE), + ('MODEL_EFI_DEPEX', MODEL_EFI_DEPEX), + ('MODEL_IDENTIFIER_UNION', MODEL_IDENTIFIER_UNION), + ('MODEL_EFI_SOURCE_FILE', MODEL_EFI_SOURCE_FILE), + ('MODEL_EFI_BINARY_FILE', MODEL_EFI_BINARY_FILE), + ('MODEL_PCD', MODEL_PCD), + ('MODEL_PCD_FIXED_AT_BUILD', MODEL_PCD_FIXED_AT_BUILD), + ('MODEL_PCD_PATCHABLE_IN_MODULE', MODEL_PCD_PATCHABLE_IN_MODULE), + ('MODEL_PCD_FEATURE_FLAG', MODEL_PCD_FEATURE_FLAG), + ('MODEL_PCD_DYNAMIC_EX', MODEL_PCD_DYNAMIC_EX), + ('MODEL_PCD_DYNAMIC_EX_DEFAULT', MODEL_PCD_DYNAMIC_EX_DEFAULT), + ('MODEL_PCD_DYNAMIC_EX_VPD', MODEL_PCD_DYNAMIC_EX_VPD), + ('MODEL_PCD_DYNAMIC_EX_HII', MODEL_PCD_DYNAMIC_EX_HII), + ('MODEL_PCD_DYNAMIC', MODEL_PCD_DYNAMIC), + ('MODEL_PCD_DYNAMIC_DEFAULT', MODEL_PCD_DYNAMIC_DEFAULT), + ('MODEL_PCD_DYNAMIC_VPD', MODEL_PCD_DYNAMIC_VPD), + ('MODEL_PCD_DYNAMIC_HII', MODEL_PCD_DYNAMIC_HII), + ("MODEL_META_DATA_HEADER", MODEL_META_DATA_HEADER), + ("MODEL_META_DATA_INCLUDE", MODEL_META_DATA_INCLUDE), + ("MODEL_META_DATA_DEFINE", MODEL_META_DATA_DEFINE), + ("MODEL_META_DATA_CONDITIONAL_STATEMENT_IF", MODEL_META_DATA_CONDITIONAL_STATEMENT_IF), + ("MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE", MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE), + ("MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF", MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF), + ("MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF", MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF), + ("MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH", MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH), + ("MODEL_META_DATA_BUILD_OPTION", MODEL_META_DATA_BUILD_OPTION), + ("MODEL_META_DATA_COMPONENT", MODEL_META_DATA_COMPONENT), + ('MODEL_META_DATA_USER_EXTENSION', MODEL_META_DATA_USER_EXTENSION), + ('MODEL_META_DATA_PACKAGE', MODEL_META_DATA_PACKAGE), + ('MODEL_META_DATA_NMAKE', MODEL_META_DATA_NMAKE) + ] + +## FunctionClass +# +# This class defines a structure of a function +# +# @param ID: ID of a Function +# @param Header: Header of a Function +# @param Modifier: Modifier of a Function +# @param Name: Name of a Function +# @param ReturnStatement: ReturnStatement of a Funciont +# @param StartLine: StartLine of a Function +# @param StartColumn: StartColumn of a Function +# @param EndLine: EndLine of a Function +# @param EndColumn: EndColumn of a Function +# @param BodyStartLine: BodyStartLine of a Function Body +# @param BodyStartColumn: BodyStartColumn of a Function Body +# @param BelongsToFile: The Function belongs to which file +# @param IdentifierList: IdentifierList of a File +# @param PcdList: PcdList of a File +# +# @var ID: ID of a Function +# @var Header: Header of a Function +# @var Modifier: Modifier of a Function +# @var Name: Name of a Function +# @var ReturnStatement: ReturnStatement of a Funciont +# @var StartLine: StartLine of a Function +# @var StartColumn: StartColumn of a Function +# @var EndLine: EndLine of a Function +# @var EndColumn: EndColumn of a Function +# @var BodyStartLine: StartLine of a Function Body +# @var BodyStartColumn: StartColumn of a Function Body +# @var BelongsToFile: The Function belongs to which file +# @var IdentifierList: IdentifierList of a File +# @var PcdList: PcdList of a File +# +class FunctionClass(object): + def __init__(self, ID = -1, Header = '', Modifier = '', Name = '', ReturnStatement = '', \ + StartLine = -1, StartColumn = -1, EndLine = -1, EndColumn = -1, \ + BodyStartLine = -1, BodyStartColumn = -1, BelongsToFile = -1, \ + IdentifierList = [], PcdList = [], \ + FunNameStartLine = -1, FunNameStartColumn = -1): + self.ID = ID + self.Header = Header + self.Modifier = Modifier + self.Name = Name + self.ReturnStatement = ReturnStatement + self.StartLine = StartLine + self.StartColumn = StartColumn + self.EndLine = EndLine + self.EndColumn = EndColumn + self.BodyStartLine = BodyStartLine + self.BodyStartColumn = BodyStartColumn + self.BelongsToFile = BelongsToFile + self.FunNameStartLine = FunNameStartLine + self.FunNameStartColumn = FunNameStartColumn + + self.IdentifierList = IdentifierList + self.PcdList = PcdList + +## IdentifierClass +# +# This class defines a structure of a variable +# +# @param ID: ID of a Identifier +# @param Modifier: Modifier of a Identifier +# @param Type: Type of a Identifier +# @param Name: Name of a Identifier +# @param Value: Value of a Identifier +# @param Model: Model of a Identifier +# @param BelongsToFile: The Identifier belongs to which file +# @param BelongsToFunction: The Identifier belongs to which function +# @param StartLine: StartLine of a Identifier +# @param StartColumn: StartColumn of a Identifier +# @param EndLine: EndLine of a Identifier +# @param EndColumn: EndColumn of a Identifier +# +# @var ID: ID of a Identifier +# @var Modifier: Modifier of a Identifier +# @var Type: Type of a Identifier +# @var Name: Name of a Identifier +# @var Value: Value of a Identifier +# @var Model: Model of a Identifier +# @var BelongsToFile: The Identifier belongs to which file +# @var BelongsToFunction: The Identifier belongs to which function +# @var StartLine: StartLine of a Identifier +# @var StartColumn: StartColumn of a Identifier +# @var EndLine: EndLine of a Identifier +# @var EndColumn: EndColumn of a Identifier +# +class IdentifierClass(object): + def __init__(self, ID = -1, Modifier = '', Type = '', Name = '', Value = '', Model = MODEL_UNKNOWN, \ + BelongsToFile = -1, BelongsToFunction = -1, StartLine = -1, StartColumn = -1, EndLine = -1, EndColumn = -1): + self.ID = ID + self.Modifier = Modifier + self.Type = Type + self.Name = Name + self.Value = Value + self.Model = Model + self.BelongsToFile = BelongsToFile + self.BelongsToFunction = BelongsToFunction + self.StartLine = StartLine + self.StartColumn = StartColumn + self.EndLine = EndLine + self.EndColumn = EndColumn + +## PcdClass +# +# This class defines a structure of a Pcd +# +# @param ID: ID of a Pcd +# @param CName: CName of a Pcd +# @param TokenSpaceGuidCName: TokenSpaceGuidCName of a Pcd +# @param Token: Token of a Pcd +# @param DatumType: DatumType of a Pcd +# @param Model: Model of a Pcd +# @param BelongsToFile: The Pcd belongs to which file +# @param BelongsToFunction: The Pcd belongs to which function +# @param StartLine: StartLine of a Pcd +# @param StartColumn: StartColumn of a Pcd +# @param EndLine: EndLine of a Pcd +# @param EndColumn: EndColumn of a Pcd +# +# @var ID: ID of a Pcd +# @var CName: CName of a Pcd +# @var TokenSpaceGuidCName: TokenSpaceGuidCName of a Pcd +# @var Token: Token of a Pcd +# @var DatumType: DatumType of a Pcd +# @var Model: Model of a Pcd +# @var BelongsToFile: The Pcd belongs to which file +# @var BelongsToFunction: The Pcd belongs to which function +# @var StartLine: StartLine of a Pcd +# @var StartColumn: StartColumn of a Pcd +# @var EndLine: EndLine of a Pcd +# @var EndColumn: EndColumn of a Pcd +# +class PcdDataClass(object): + def __init__(self, ID = -1, CName = '', TokenSpaceGuidCName = '', Token = '', DatumType = '', Model = MODEL_UNKNOWN, \ + BelongsToFile = -1, BelongsToFunction = -1, StartLine = -1, StartColumn = -1, EndLine = -1, EndColumn = -1): + self.ID = ID + self.CName = CName + self.TokenSpaceGuidCName = TokenSpaceGuidCName + self.Token = Token + self.DatumType = DatumType + self.BelongsToFile = BelongsToFile + self.BelongsToFunction = BelongsToFunction + self.StartLine = StartLine + self.StartColumn = StartColumn + self.EndLine = EndLine + self.EndColumn = EndColumn + +## FileClass +# +# This class defines a structure of a file +# +# @param ID: ID of a File +# @param Name: Name of a File +# @param ExtName: ExtName of a File +# @param Path: Path of a File +# @param FullPath: FullPath of a File +# @param Model: Model of a File +# @param TimeStamp: TimeStamp of a File +# @param FunctionList: FunctionList of a File +# @param IdentifierList: IdentifierList of a File +# @param PcdList: PcdList of a File +# +# @var ID: ID of a File +# @var Name: Name of a File +# @var ExtName: ExtName of a File +# @var Path: Path of a File +# @var FullPath: FullPath of a File +# @var Model: Model of a File +# @var TimeStamp: TimeStamp of a File +# @var FunctionList: FunctionList of a File +# @var IdentifierList: IdentifierList of a File +# @var PcdList: PcdList of a File +# +class FileClass(object): + def __init__(self, ID = -1, Name = '', ExtName = '', Path = '', FullPath = '', Model = MODEL_UNKNOWN, TimeStamp = '', \ + FunctionList = [], IdentifierList = [], PcdList = []): + self.ID = ID + self.Name = Name + self.ExtName = ExtName + self.Path = Path + self.FullPath = FullPath + self.Model = Model + self.TimeStamp = TimeStamp + + self.FunctionList = FunctionList + self.IdentifierList = IdentifierList + self.PcdList = PcdList diff --git a/BaseTools/Source/Python/CommonDataClass/DistributionPackageClass.py b/BaseTools/Source/Python/CommonDataClass/DistributionPackageClass.py new file mode 100644 index 0000000000..cd8bd4cb7f --- /dev/null +++ b/BaseTools/Source/Python/CommonDataClass/DistributionPackageClass.py @@ -0,0 +1,159 @@ +## @file +# This file is used to define a class object to describe a distribution package +# +# Copyright (c) 2008, 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 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.path +from CommonClass import * +from Common.Misc import sdict +from Common.Misc import GetFiles +from Common.DecClassObjectLight import Dec +from Common.InfClassObjectLight import Inf +from Common.XmlParser import * + +## DistributionPackageHeaderClass +# +class DistributionPackageHeaderClass(IdentificationClass, CommonHeaderClass): + def __init__(self): + IdentificationClass.__init__(self) + CommonHeaderClass.__init__(self) + self.ReadOnly = 'False' + self.RePackage = 'True' + self.Vendor = '' + self.Date = '' + self.Signature = 'Md5Sum' + self.XmlSpecification = '' + +## DistributionPackageClass +# +# +class DistributionPackageClass(object): + def __init__(self): + self.Header = DistributionPackageHeaderClass() + self.PackageSurfaceArea = sdict() # {(Guid, Version, Path) : PackageObj} + self.ModuleSurfaceArea = sdict() # {(Guid, Version, Path) : ModuleObj} + self.Tools = MiscFileClass() + self.MiscellaneousFiles = MiscFileClass() + self.UserExtensions = [] + + ## 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): + AllGuidVersionDict = {} + # Get Packages + if PackageList: + for PackageFile in PackageList: + PackageFileFullPath = os.path.normpath(os.path.join(WorkspaceDir, PackageFile)) + DecObj = Dec(PackageFileFullPath, True, WorkspaceDir) + PackageObj = DecObj.Package + AllGuidVersionDict[PackageFileFullPath] = [PackageObj.PackageHeader.Guid, PackageObj.PackageHeader.Version] + + # Parser inf file one bye one + for File in PackageObj.MiscFiles.Files: + Filename = os.path.normpath(os.path.join(PackageObj.PackageHeader.RelaPath, File.Filename)) + (Name, ExtName) = os.path.splitext(Filename) + if ExtName.upper() == '.INF': + InfObj = Inf(Filename, True, WorkspaceDir, DecObj.Identification.PackagePath) + ModuleObj = InfObj.Module + AllGuidVersionDict[File] = [ModuleObj.ModuleHeader.Guid, ModuleObj.ModuleHeader.Version] + # Find and update Guid/Version of LibraryClass + for Item in ModuleObj.LibraryClasses: + if Item.RecommendedInstance: + LibClassIns = os.path.normpath(os.path.join(WorkspaceDir, Item.RecommendedInstance)) + Guid, Version = '', '' + if LibClassIns in AllGuidVersionDict: + Guid = AllGuidVersionDict[LibClassIns][0] + Version = AllGuidVersionDict[LibClassIns][1] + else: + Lib = Inf(LibClassIns, True, WorkspaceDir) + Guid = Lib.Module.ModuleHeader.Guid + Version = Lib.Module.ModuleHeader.Version + AllGuidVersionDict[LibClassIns] = [Guid, Version] + Item.RecommendedInstanceGuid = Guid + Item.RecommendedInstanceVersion = Version + # Find and update Guid/Version of + for Item in ModuleObj.PackageDependencies: + if Item.FilePath: + PackageFilePath = os.path.normpath(os.path.join(WorkspaceDir, Item.FilePath)) + Guid, Version = '', '' + if PackageFilePath in AllGuidVersionDict: + Guid = AllGuidVersionDict[PackageFilePath][0] + Version = AllGuidVersionDict[PackageFilePath][1] + else: + PackageDependencies = Dec(PackageFilePath, True, WorkspaceDir) + Guid = PackageDependencies.Package.PackageHeader.Guid + Version = PackageDependencies.Package.PackageHeader.Version + AllGuidVersionDict[PackageFilePath] = [Guid, Version] + Item.PackageGuid = Guid + Item.PackageVersion = Version + + # Add module to package + PackageObj.Modules[(ModuleObj.ModuleHeader.Guid, ModuleObj.ModuleHeader.Version, ModuleObj.ModuleHeader.CombinePath)] = ModuleObj + self.PackageSurfaceArea[(PackageObj.PackageHeader.Guid, PackageObj.PackageHeader.Version, PackageObj.PackageHeader.CombinePath)] = PackageObj + + # Get Modules + if ModuleList: + for ModuleFile in ModuleList: + ModuleFileFullPath = os.path.normpath(os.path.join(WorkspaceDir, ModuleFile)) + InfObj = Inf(ModuleFileFullPath, True, WorkspaceDir) + ModuleObj = InfObj.Module + AllGuidVersionDict[ModuleFileFullPath] = [ModuleObj.ModuleHeader.Guid, ModuleObj.ModuleHeader.Version] + # Find and update Guid/Version of LibraryClass + for Item in ModuleObj.LibraryClasses: + if Item.RecommendedInstance: + LibClassIns = os.path.normpath(os.path.join(WorkspaceDir, Item.RecommendedInstance)) + Guid, Version = '', '' + if LibClassIns in AllGuidVersionDict: + Guid = AllGuidVersionDict[LibClassIns][0] + Version = AllGuidVersionDict[LibClassIns][1] + else: + Lib = Inf(LibClassIns, True, WorkspaceDir) + Guid = Lib.Module.ModuleHeader.Guid + Version = Lib.Module.ModuleHeader.Version + AllGuidVersionDict[LibClassIns] = [Guid, Version] + Item.RecommendedInstanceGuid = Guid + Item.RecommendedInstanceVersion = Version + # Find and update Guid/Version of + for Item in ModuleObj.PackageDependencies: + if Item.FilePath: + PackageFilePath = os.path.normpath(os.path.join(WorkspaceDir, Item.FilePath)) + Guid, Version = '', '' + if PackageFilePath in AllGuidVersionDict: + Guid = AllGuidVersionDict[PackageFilePath][0] + Version = AllGuidVersionDict[PackageFilePath][1] + else: + PackageDependencies = Dec(PackageFilePath, True, WorkspaceDir) + Guid = PackageDependencies.Package.PackageHeader.Guid + Version = PackageDependencies.Package.PackageHeader.Version + AllGuidVersionDict[PackageFilePath] = [Guid, Version] + Item.PackageGuid = Guid + Item.PackageVersion = Version + self.ModuleSurfaceArea[(ModuleObj.ModuleHeader.Guid, ModuleObj.ModuleHeader.Version, ModuleObj.ModuleHeader.CombinePath)] = ModuleObj + +## +# +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +# +if __name__ == '__main__': + pass + D = DistributionPackageClass() + D.GetDistributionPackage(os.getenv('WORKSPACE'), ['MdePkg/MdePkg.dec', 'TianoModulePkg/TianoModulePkg.dec'], ['MdeModulePkg/Application/HelloWorld/HelloWorld.inf']) + Xml = DistributionPackageXml() + print Xml.ToXml(D) + E = Xml.FromXml('C:\\2.xml') + #print Xml.ToXml(E) diff --git a/BaseTools/Source/Python/CommonDataClass/FdfClass.py b/BaseTools/Source/Python/CommonDataClass/FdfClass.py new file mode 100644 index 0000000000..a9e12ed46d --- /dev/null +++ b/BaseTools/Source/Python/CommonDataClass/FdfClass.py @@ -0,0 +1,402 @@ +## @file +# classes represent data in FDF +# +# Copyright (c) 2007, 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 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. +# + +## FD data in FDF +# +# +class FDClassObject: + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + self.FdUiName = '' + self.CreateFileName = None + self.BaseAddress = None + self.BaseAddressPcd = None + self.Size = None + self.SizePcd = None + self.ErasePolarity = '1' + # 3-tuple list (blockSize, numBlocks, pcd) + self.BlockSizeList = [] + # DefineVarDict[var] = value + self.DefineVarDict = {} + # SetVarDict[var] = value + self.SetVarDict = {} + self.RegionList = [] + self.vtfRawDict = {} + +## FV data in FDF +# +# +class FvClassObject: + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + self.UiFvName = None + self.CreateFileName = None + # 3-tuple list (blockSize, numBlocks, pcd) + self.BlockSizeList = [] + # DefineVarDict[var] = value + self.DefineVarDict = {} + # SetVarDict[var] = value + self.SetVarDict = {} + self.FvAlignment = None + # FvAttributeDict[attribute] = TRUE/FALSE (1/0) + self.FvAttributeDict = {} + self.FvNameGuid = None + self.AprioriSectionList = [] + self.FfsList = [] + self.BsBaseAddress = None + self.RtBaseAddress = None + +## Region data in FDF +# +# +class RegionClassObject: + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + self.Offset = None # The begin position of the Region + self.Size = None # The Size of the Region + self.PcdOffset = None + self.PcdSize = None + self.SetVarDict = {} + self.RegionType = None + self.RegionDataList = [] + +## FFS data in FDF +# +# +class FfsClassObject: + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + self.NameGuid = None + self.Fixed = False + self.CheckSum = False + self.Alignment = None + self.SectionList = [] + +## FILE statement data in FDF +# +# +class FileStatementClassObject (FfsClassObject) : + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + FfsClassObject.__init__(self) + self.FvFileType = None + self.FileName = None + self.KeyStringList = [] + self.FvName = None + self.FdName = None + self.DefineVarDict = {} + self.AprioriSection = None + self.KeepReloc = None + +## INF statement data in FDF +# +# +class FfsInfStatementClassObject(FfsClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + FfsClassObject.__init__(self) + self.Rule = None + self.Version = None + self.Ui = None + self.InfFileName = None + self.BuildNum = '' + self.KeyStringList = [] + self.KeepReloc = None + self.UseArch = None + +## APRIORI section data in FDF +# +# +class AprioriSectionClassObject: + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + # DefineVarDict[var] = value + self.DefineVarDict = {} + self.FfsList = [] + +## section data in FDF +# +# +class SectionClassObject: + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + self.Alignment = None + +## Depex expression section in FDF +# +# +class DepexSectionClassObject (SectionClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + self.DepexType = None + self.Expression = None + +## Compress section data in FDF +# +# +class CompressSectionClassObject (SectionClassObject) : + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + SectionClassObject.__init__(self) + self.CompType = None + self.SectionList = [] + +## Data section data in FDF +# +# +class DataSectionClassObject (SectionClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + SectionClassObject.__init__(self) + self.SecType = None + self.SectFileName = None + self.SectionList = [] + self.KeepReloc = True + +## Rule section data in FDF +# +# +class EfiSectionClassObject (SectionClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + SectionClassObject.__init__(self) + self.SectionType = None + self.Optional = False + self.FileType = None + self.StringData = None + self.FileName = None + self.FileExtension = None + self.BuildNum = None + self.KeepReloc = None + +## FV image section data in FDF +# +# +class FvImageSectionClassObject (SectionClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + SectionClassObject.__init__(self) + self.Fv = None + self.FvName = None + self.FvFileType = None + self.FvFileName = None + self.FvFileExtension = None + +## GUIDed section data in FDF +# +# +class GuidSectionClassObject (SectionClassObject) : + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + SectionClassObject.__init__(self) + self.NameGuid = None + self.SectionList = [] + self.SectionType = None + self.ProcessRequired = False + self.AuthStatusValid = False + +## UI section data in FDF +# +# +class UiSectionClassObject (SectionClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + SectionClassObject.__init__(self) + self.StringData = None + self.FileName = None + +## Version section data in FDF +# +# +class VerSectionClassObject (SectionClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + SectionClassObject.__init__(self) + self.BuildNum = None + self.StringData = None + self.FileName = None + +## Rule data in FDF +# +# +class RuleClassObject : + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + self.Arch = None + self.ModuleType = None # For Module Type + self.TemplateName = None + self.NameGuid = None + self.Fixed = False + self.Alignment = None + self.CheckSum = False + self.FvFileType = None # for Ffs File Type + self.KeyStringList = [] + self.KeepReloc = None + +## Complex rule data in FDF +# +# +class RuleComplexFileClassObject(RuleClassObject) : + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + RuleClassObject.__init__(self) + self.SectionList = [] + +## Simple rule data in FDF +# +# +class RuleSimpleFileClassObject(RuleClassObject) : + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + RuleClassObject.__init__(self) + self.FileName = None + self.SectionType = '' + self.FileExtension = None + +## File extension rule data in FDF +# +# +class RuleFileExtensionClassObject(RuleClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + RuleClassObject.__init__(self) + self.FileExtension = None + +## Capsule data in FDF +# +# +class CapsuleClassObject : + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + self.SpecName = None + self.UiCapsuleName = None + self.CreateFile = None + self.GroupIdNumber = None + # DefineVarDict[var] = value + self.DefineVarDict = {} + # SetVarDict[var] = value + self.SetVarDict = {} + # TokensDict[var] = value + self.TokensDict = {} + self.CapsuleDataList = [] + +## VTF data in FDF +# +# +class VtfClassObject : + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + self.KeyArch = None + self.ArchList = None + self.UiName = None + self.ResetBin = None + self.ComponentStatementList = [] + +## VTF component data in FDF +# +# +class ComponentStatementClassObject : + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + self.CompName = None + self.CompLoc = None + self.CompType = None + self.CompVer = None + self.CompCs = None + self.CompBin = None + self.CompSym = None + self.CompSize = None + self.FilePos = None + +## OptionROM data in FDF +# +# +class OptionRomClassObject: + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + self.DriverName = None + self.FfsList = [] + \ No newline at end of file diff --git a/BaseTools/Source/Python/CommonDataClass/ModuleClass.py b/BaseTools/Source/Python/CommonDataClass/ModuleClass.py new file mode 100644 index 0000000000..9d780725b9 --- /dev/null +++ b/BaseTools/Source/Python/CommonDataClass/ModuleClass.py @@ -0,0 +1,486 @@ +## @file +# This file is used to define a class object to describe a module +# +# Copyright (c) 2007, 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 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 +# +from CommonClass import * + +## ModuleHeaderClass +# +# This class defined header items used in Module file +# +# @param IdentificationClass: Inherited from IdentificationClass class +# @param CommonHeaderClass: Inherited from CommonHeaderClass class +# @param DefineClass: Inherited from DefineClass class +# +# @var ModuleType: To store value for ModuleType +# @var SupArchList: To store value for SupArchList, selection scope is in below list +# EBC | IA32 | X64 | IPF | ARM | PPC +# @var BinaryModule: To store value for BinaryModule +# @var OutputFileBasename: To store value for OutputFileBasename +# @var ClonedFrom: To store value for ClonedFrom, it is a set structure as +# [ ClonedRecordClass, ... ] +# @var PcdIsDriver: To store value for PcdIsDriver, selection scope is in below list +# PEI_PCD_DRIVER | DXE_PCD_DRIVER +# @var TianoR8FlashMap_h: To store value for TianoR8FlashMap_h +# @var InfVersion: To store value for InfVersion +# @var EfiSpecificationVersion: To store value for EfiSpecificationVersion +# @var EdkReleaseVersion: To store value for EdkReleaseVersion +# @var LibraryClass: To store value for LibraryClass, it is a set structure as +# [ LibraryClassClass, ...] +# @var ComponentType: To store value for ComponentType, selection scope is in below list +# LIBRARY | SECURITY_CORE | PEI_CORE | COMBINED_PEIM_DRIVER | PIC_PEIM | RELOCATABLE_PEIM | BS_DRIVER | RT_DRIVER | SAL_RT_DRIVER | APPLICATION +# @var MakefileName: To store value for MakefileName +# @var BuildNumber: To store value for BuildNumber +# @var BuildType: To store value for BuildType +# @var FfsExt: To store value for FfsExt +# @var FvExt: To store value for FvExt +# @var SourceFv: To store value for SourceFv +# @var CustomMakefile: To store value for CustomMakefile, it is a set structure as +# { Family : Filename, ... } +# @var Shadow: To store value for Shadow +# @var MacroDefines To store the defined macros +# +class ModuleHeaderClass(IdentificationClass, CommonHeaderClass, DefineClass): + def __init__(self): + IdentificationClass.__init__(self) + CommonHeaderClass.__init__(self) + DefineClass.__init__(self) + self.ModuleType = '' + self.SupModuleList = [] + self.SupArchList = [] + self.BinaryModule = False + self.OutputFileBasename = '' + self.ClonedFrom = [] + self.PcdIsDriver = '' + self.TianoR8FlashMap_h = False + self.InfVersion = '' + self.EfiSpecificationVersion = '' + self.PiSpecificationVersion = '' + self.UefiSpecificationVersion = '' + self.EdkReleaseVersion = '' + self.LibraryClass = [] + self.ComponentType = '' + self.MakefileName = '' + self.BuildNumber = '' + self.BuildType = '' + self.FfsExt = '' + self.FvExt = '' + self.SourceFv = '' + self.CustomMakefile = {} + self.Shadow = '' + self.MacroDefines = {} + self.SourceOverridePath = '' + self.Specification = [] + +## ModuleSourceFileClass +# +# This class defined source file item used in Module file +# +# @param CommonClass: Inherited from CommonClass class +# @param SourceFile: Input value for SourceFile, default is '' +# @param TagName: Input value for TagName, default is '' +# @param ToolCode: Input value for ToolCode, default is '' +# @param ToolChainFamily: Input value for ToolChainFamily, default is '' +# @param FeatureFlag: Input value for FeatureFlag, default is '' +# @param SupArchList: Input value for SupArchList, default is [] +# +# @var SourceFile: To store value for SourceFile +# @var TagName: To store value for TagName +# @var ToolCode: To store value for ToolCode +# @var ToolChainFamily: To store value for ToolChainFamily +# +class ModuleSourceFileClass(CommonClass): + def __init__(self, SourceFile = '', TagName = '', ToolCode = '', ToolChainFamily = '', FeatureFlag = '', SupArchList = None): + self.SourceFile = SourceFile + self.TagName = TagName + self.ToolCode = ToolCode + self.ToolChainFamily = ToolChainFamily + self.FileType = '' + CommonClass.__init__(self, FeatureFlag = FeatureFlag, SupArchList = SupArchList) + +## ModuleBinaryFileClass +# +# This class defined binary file item used in Module file +# +# @param CommonClass: Inherited from CommonClass class +# @param BinaryFile: Input value for BinaryFile, default is '' +# @param FileType: Input value for FileType, default is '' +# @param FeatureFlag: Input value for FeatureFlag, default is '' +# @param SupArchList: Input value for SupArchList, default is [] +# +# @var BinaryFile: To store value for BinaryFile +# @var FileType: To store value for FileType, selection scope is in below list +# FW | GUID | PREEFORM | UEFI_APP | UNI_UI | UNI_VER | LIB | PE32 | PIC | PEI_DEPEX | DXE_DEPEX | TE | VER | UI | BIN | FV +# @var Target: To store value for Target +# @var ToolChainFamily: To store value for ToolChainFamily +# +class ModuleBinaryFileClass(CommonClass): + def __init__(self, BinaryFile = '', FileType = '', Target = '', FeatureFlag = '', SupArchList = None): + self.BinaryFile = BinaryFile + self.FileType = FileType + self.Target = Target + CommonClass.__init__(self, FeatureFlag = FeatureFlag, SupArchList = SupArchList) + self.Filenames = [] + self.PatchPcdValues = [] + self.PcdExValues = [] + self.LibraryInstances = [] + self.BuildFlags = [] + +## ModulePackageDependencyClass +# +# This class defined package dependency item used in Module file +# +# @param CommonClass: Inherited from CommonClass class +# @param DefineClass: Input value for DefineClass class +# +# @var FilePath: To store value for FilePath +# @var PackageName: To store value for PackageName +# @var PackageVersion: To store value for PackageVersion +# @var PackageGuid: To store value for PackageGuid +# +class ModulePackageDependencyClass(CommonClass, DefineClass): + def __init__(self): + self.FilePath = '' + self.PackageName = '' + self.PackageVersion = '' + self.PackageGuid = '' + self.Description = '' + CommonClass.__init__(self) + DefineClass.__init__(self) + +## ModuleLibraryClass +# +# This class defined library item used in Module file +# +# @param CommonClass: Inherited from CommonClass class +# +# @var Library: To store value for Library +# +class ModuleLibraryClass(CommonClass): + def __init__(self): + self.Library = '' + CommonClass.__init__(self) + +## ModuleEventClass +# +# This class defined event item used in Module file +# +# @param CommonClass: Inherited from CommonClass class +# +# @var CName: To store value for CName +# @var GuidCName: To store value for GuidCName +# @var Type: To store value for Type, selection scope is in below list +# CREATE_EVENT | SIGNAL_EVENT +# +class ModuleEventClass(CommonClass): + def __init__(self): + self.CName = '' + self.GuidCName = '' + self.Type = '' + CommonClass.__init__(self) + +## ModuleHobClass +# +# This class defined hob item used in Module file +# +# @param CommonClass: Inherited from CommonClass class +# +# @var GuidCName: To store value for GuidCName +# @var Type: To store value for Type, selection scope is in below list +# PHIT | MEMORY_ALLOCATION | RESOURCE_DESCRIPTOR | GUID_EXTENSION | FIRMWARE_VOLUME | CPU | POOL | CAPSULE_VOLUME +# +class ModuleHobClass(CommonClass): + def __init__(self): + self.Type = '' + self.GuidCName = '' + CommonClass.__init__(self) + +## ModuleVariableClass +# +# This class defined variable item used in Module file +# +# @param CommonClass: Inherited from CommonClass class +# +# @var GuidCName: To store value for GuidCName +# @var Name: To store value for Name +# +class ModuleVariableClass(CommonClass): + def __init__(self): + self.Name = '' + self.GuidCName = '' + CommonClass.__init__(self) + +## ModuleBootModeClass +# +# This class defined boot mode item used in Module file +# +# @param CommonClass: Inherited from CommonClass class +# +# @var Name: To store value for Name, selection scope is in below 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 +# +class ModuleBootModeClass(CommonClass): + def __init__(self): + self.Name = '' + CommonClass.__init__(self) + +## ModuleSystemTableClass +# +# This class defined system table item used in Module file +# +# @param CommonClass: Inherited from CommonClass class +# +# @var CName: To store value for CName +# +class ModuleSystemTableClass(CommonClass): + def __init__(self): + self.CName = '' + CommonClass.__init__(self) + +## ModuleDataHubClass +# +# This class defined data hub item used in Module file +# +# @param CommonClass: Inherited from CommonClass class +# +# @var CName: To store value for CName +# +class ModuleDataHubClass(CommonClass): + def __init__(self): + self.CName = '' + CommonClass.__init__(self) + +## ModuleHiiPackageClass +# +# This class defined Hii package item used in Module file +# +# @param CommonClass: Inherited from CommonClass class +# +# @var CName: To store value for CName +# +class ModuleHiiPackageClass(CommonClass): + def __init__(self): + self.CName = '' + CommonClass.__init__(self) + +## ModuleExternImageClass +# +# This class defined Extern Image item used in Module file +# +# @param object: Inherited from object class +# +# @var ModuleEntryPoint: To store value for ModuleEntryPoint +# @var ModuleUnloadImage: To store value for ModuleUnloadImage +# +class ModuleExternImageClass(object): + def __init__(self): + self.ModuleEntryPoint = '' + self.ModuleUnloadImage = '' + +## ModuleExternLibraryClass +# +# This class defined Extern Library item used in Module file +# +# @param object: Inherited from object class +# +# @var Constructor: To store value for Constructor +# @var Destructor: To store value for Destructor +# +class ModuleExternLibraryClass(object): + def __init__(self): + self.Constructor = '' + self.Destructor = '' + +## ModuleExternDriverClass +# +# This class defined Extern Driver item used in Module file +# +# @param object: Inherited from object class +# +# @var DriverBinding: To store value for DriverBinding +# @var ComponentName: To store value for ComponentName +# @var DriverConfig: To store value for DriverConfig +# @var DriverDiag: To store value for DriverDiag +# +class ModuleExternDriverClass(object): + def __init__(self): + self.DriverBinding= '' + self.ComponentName = '' + self.DriverConfig = '' + self.DriverDiag = '' + +## ModuleExternCallBackClass +# +# This class defined Extern Call Back item used in Module file +# +# @param object: Inherited from object class +# +# @var SetVirtualAddressMapCallBack: To store value for SetVirtualAddressMapCallBack +# @var ExitBootServicesCallBack: To store value for ExitBootServicesCallBack +# +class ModuleExternCallBackClass(object): + def __init__(self): + self.SetVirtualAddressMapCallBack = '' + self.ExitBootServicesCallBack = '' + +## ModuleExternClass +# +# This class defined Extern used in Module file +# +# @param object: Inherited from object class +# +# +class ModuleExternClass(CommonClass): + def __init__(self): + self.EntryPoint = '' + self.UnloadImage = '' + self.Constructor = '' + self.Destructor = '' + CommonClass.__init__(self) + +## ModuleDepexClass +# +# This class defined depex item used in Module file +# +# @param CommonClass: Inherited from CommonClass class +# @param DefineClass: Input value for DefineClass class +# +# @var Depex: To store value for Depex +# +class ModuleDepexClass(CommonClass, DefineClass): + def __init__(self): + CommonClass.__init__(self) + DefineClass.__init__(self) + self.Depex = '' + +## ModuleNmakeClass +# +# This class defined nmake item used in Module file +# +# @param CommonClass: Inherited from CommonClass class +# +# @var Name: To store value for Name +# @var Value: To store value for Value +# +class ModuleNmakeClass(CommonClass): + def __init__(self): + CommonClass.__init__(self) + self.Name = '' + self.Value = '' + +## ModuleClass +# +# This class defined a complete module item +# +# @param object: Inherited from object class +# +# @var Header: To store value for Header, it is a structure as +# {Arch : ModuleHeaderClass} +# @var LibraryClasses: To store value for LibraryClasses, it is a list structure as +# [ LibraryClassClass, ...] +# @var Libraries: To store value for Libraries, it is a list structure as +# [ ModuleLibraryClass, ...] +# @var Sources: To store value for Sources, it is a list structure as +# [ ModuleSourceFileClass, ...] +# @var Binaries: To store value for Binaries, it is a list structure as +# [ ModuleBinaryFileClass, ...] +# @var NonProcessedFiles: To store value for NonProcessedFiles, it is a list structure as +# [ '', '', ...] +# @var PackageDependencies: To store value for PackageDependencies, it is a list structure as +# [ ModulePackageDependencyClass, ... ] +# @var Nmake: To store value for Nmake, it is a list structure as +# [ ModuleNmakeClass, ... ] +# @var Depex: To store value for Depex, it is a list structure as +# [ ModuleDepexClass, ... ] +# @var Includes: To store value for Includes, it is a list structure as +# [ IncludeClass, ...] +# @var Protocols: To store value for Protocols, it is a list structure as +# [ ProtocolClass, ...] +# @var Ppis: To store value for Ppis, it is a list structure as +# [ PpiClass, ...] +# @var Events: To store value for Events, it is a list structure as +# [ ModuleEventClass, ...] +# @var Hobs: To store value for Hobs, it is a list structure as +# [ ModuleHobClass, ...] +# @var Variables: To store value for Variables, it is a list structure as +# [ ModuleVariableClass, ...] +# @var BootModes: To store value for BootModes, it is a list structure as +# [ ModuleBootModeClass, ...] +# @var SystemTables: To store value for SystemTables, it is a list structure as +# [ ModuleSystemTableClass, ...] +# @var DataHubs: To store value for DataHubs, it is a list structure as +# [ ModuleDataHubClass, ...] +# @var HiiPackages: To store value for HiiPackages, it is a list structure as +# [ ModuleHiiPackageClass, ...] +# @var Guids: To store value for Guids, it is a list structure as +# [ GuidClass, ...] +# @var PcdCodes: To store value for PcdCodes, it is a list structure as +# [ PcdClass, ...] +# @var ExternImages: To store value for ExternImages, it is a list structure as +# [ ModuleExternImageClass, ...] +# @var ExternLibraries: To store value for ExternLibraries, it is a list structure as +# [ ModuleExternLibraryClass, ...] +# @var ExternDrivers: To store value for ExternDrivers, it is a list structure as +# [ ModuleExternDriverClass, ...] +# @var ExternCallBacks: To store value for ExternCallBacks, it is a list structure as +# [ ModuleExternCallBackClass, ...] +# @var BuildOptions: To store value for BuildOptions, it is a list structure as +# [ BuildOptionClass, ...] +# @var UserExtensions: To store value for UserExtensions, it is a list structure as +# [ UserExtensionsClass, ...] +# +class ModuleClass(object): + def __init__(self): + self.Header = {} + self.ModuleHeader = ModuleHeaderClass() + self.LibraryClasses = [] + self.Libraries = [] + self.Sources = [] + self.Binaries = [] + self.NonProcessedFiles = [] + self.PackageDependencies = [] + self.Nmake = [] + self.Depex = [] + self.PeiDepex = None + self.DxeDepex = None + self.SmmDepex = None + self.Includes = [] + self.Protocols = [] + self.Ppis = [] + self.Events = [] + self.Hobs = [] + self.Variables = [] + self.BootModes = [] + self.SystemTables = [] + self.DataHubs = [] + self.HiiPackages = [] + self.Guids = [] + self.PcdCodes = [] + self.ExternImages = [] + self.ExternLibraries = [] + self.ExternDrivers = [] + self.ExternCallBacks = [] + self.Externs = [] + self.BuildOptions = [] + self.UserExtensions = None + self.MiscFiles = None + self.FileList = [] + +## +# +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +# +if __name__ == '__main__': + M = ModuleClass() diff --git a/BaseTools/Source/Python/CommonDataClass/PackageClass.py b/BaseTools/Source/Python/CommonDataClass/PackageClass.py new file mode 100644 index 0000000000..c064f25ddb --- /dev/null +++ b/BaseTools/Source/Python/CommonDataClass/PackageClass.py @@ -0,0 +1,127 @@ +## @file +# This file is used to define a class object to describe a package +# +# Copyright (c) 2007, 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 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 +# +from CommonClass import * +from Common.Misc import sdict + +## PackageHeaderClass +# +# This class defined header items used in Package file +# +# @param IdentificationClass: Inherited from IdentificationClass class +# @param CommonHeaderClass: Inherited from CommonHeaderClass class +# +# @var DecSpecification: To store value for DecSpecification +# @var ReadOnly: To store value for ReadOnly +# @var RePackage: To store value for RePackage +# @var ClonedFrom: To store value for ClonedFrom, it is a set structure as +# [ ClonedRecordClass, ...] +# +class PackageHeaderClass(IdentificationClass, CommonHeaderClass): + def __init__(self): + IdentificationClass.__init__(self) + CommonHeaderClass.__init__(self) + self.DecSpecification = '' + self.ReadOnly = False + self.RePackage = False + self.PackagePath = '' + self.ClonedFrom = [] + +## PackageIndustryStdHeaderClass +# +# This class defined industry std header items used in Package file +# +# @param CommonHeaderClass: Inherited from CommonHeaderClass class +# +# @var Name: To store value for Name +# @var IncludeHeader: To store value for IncludeHeader +# +class PackageIndustryStdHeaderClass(CommonClass): + def __init__(self): + self.Name = '' + self.IncludeHeader = '' + CommonClass.__init__(self) + +## PackageIncludePkgHeaderClass +# +# This class defined include Pkg header items used in Package file +# +# @param object: Inherited from object class +# +# @var IncludeHeader: To store value for IncludeHeader +# @var ModuleType: To store value for ModuleType, it is a set structure as +# BASE | SEC | PEI_CORE | PEIM | DXE_CORE | DXE_DRIVER | DXE_RUNTIME_DRIVER | DXE_SAL_DRIVER | DXE_SMM_DRIVER | TOOL | UEFI_DRIVER | UEFI_APPLICATION | USER_DEFINED +# +class PackageIncludePkgHeaderClass(object): + def __init__(self): + self.IncludeHeader = '' + self.ModuleType = [] + +## PackageClass +# +# This class defined a complete package item +# +# @param object: Inherited from object class +# +# @var Header: To store value for Header, it is a structure as +# {Arch : PackageHeaderClass} +# @var Includes: To store value for Includes, it is a list structure as +# [ IncludeClass, ...] +# @var LibraryClassDeclarations: To store value for LibraryClassDeclarations, it is a list structure as +# [ LibraryClassClass, ...] +# @var IndustryStdHeaders: To store value for IndustryStdHeaders, it is a list structure as +# [ PackageIndustryStdHeader, ...] +# @var ModuleFiles: To store value for ModuleFiles, it is a list structure as +# [ '', '', ...] +# @var PackageIncludePkgHeaders: To store value for PackageIncludePkgHeaders, it is a list structure as +# [ PackageIncludePkgHeader, ...] +# @var GuidDeclarations: To store value for GuidDeclarations, it is a list structure as +# [ GuidClass, ...] +# @var ProtocolDeclarations: To store value for ProtocolDeclarations, it is a list structure as +# [ ProtocolClass, ...] +# @var PpiDeclarations: To store value for PpiDeclarations, it is a list structure as +# [ PpiClass, ...] +# @var PcdDeclarations: To store value for PcdDeclarations, it is a list structure as +# [ PcdClass, ...] +# @var UserExtensions: To store value for UserExtensions, it is a list structure as +# [ UserExtensionsClass, ...] +# +class PackageClass(object): + def __init__(self): + self.PackageHeader = PackageHeaderClass() + self.Header = {} + self.Includes = [] + self.LibraryClassDeclarations = [] + self.IndustryStdHeaders = [] + self.ModuleFiles = [] + # {[Guid, Value, Path(relative to WORKSPACE)]: ModuleClassObj} + self.Modules = sdict() + self.PackageIncludePkgHeaders = [] + self.GuidDeclarations = [] + self.ProtocolDeclarations = [] + self.PpiDeclarations = [] + self.PcdDeclarations = [] + self.PcdChecks = [] + self.UserExtensions = UserExtensionsClass() + self.MiscFiles = MiscFileClass() + self.FileList = [] + +## +# +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +# +if __name__ == '__main__': + P = PackageClass() diff --git a/BaseTools/Source/Python/CommonDataClass/PlatformClass.py b/BaseTools/Source/Python/CommonDataClass/PlatformClass.py new file mode 100644 index 0000000000..1966fb9f8c --- /dev/null +++ b/BaseTools/Source/Python/CommonDataClass/PlatformClass.py @@ -0,0 +1,432 @@ +## @file +# This file is used to define a class object to describe a platform +# +# Copyright (c) 2007, 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 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 +# +from CommonClass import * + +## SkuInfoListClass +# +# This class defined sku info list item used in platform file +# +# @param IncludeStatementClass: Inherited from IncludeStatementClass class +# +# @var SkuInfoList: To store value for SkuInfoList, it is a set structure as +# { SkuName : SkuId } +# +class SkuInfoListClass(IncludeStatementClass): + def __init__(self): + IncludeStatementClass.__init__(self) + self.SkuInfoList = {} + +## PlatformHeaderClass +# +# This class defined header items used in Platform file +# +# @param IdentificationClass: Inherited from IdentificationClass class +# @param CommonHeaderClass: Inherited from CommonHeaderClass class +# @param DefineClass: Inherited from DefineClass class +# +# @var DscSpecification: To store value for DscSpecification +# @var SupArchList: To store value for SupArchList, selection scope is in below list +# EBC | IA32 | X64 | IPF | ARM | PPC +# @var BuildTargets: To store value for BuildTargets, selection scope is in below list +# RELEASE | DEBUG +# @var IntermediateDirectories: To store value for IntermediateDirectories, selection scope is in below list +# MODULE | UNIFIED +# @var OutputDirectory: To store value for OutputDirectory +# @var ForceDebugTarget: To store value for ForceDebugTarget +# @var SkuIdName: To store value for SkuIdName +# @var BuildNumber: To store value for BuildNumber +# @var MakefileName: To store value for MakefileName +# @var ClonedFrom: To store value for ClonedFrom, it is a list structure as +# [ ClonedRecordClass, ... ] +# +class PlatformHeaderClass(IdentificationClass, CommonHeaderClass, DefineClass): + def __init__(self): + IdentificationClass.__init__(self) + CommonHeaderClass.__init__(self) + DefineClass.__init__(self) + self.DscSpecification = '' + self.SupArchList = [] + self.BuildTargets = [] + self.IntermediateDirectories = '' + self.OutputDirectory = '' + self.ForceDebugTarget = '' + self.SkuIdName = [] + self.BuildNumber = '' + self.MakefileName = '' + self.ClonedFrom = [] + +## PlatformFlashDefinitionFileClass +# +# This class defined FlashDefinitionFile item used in platform file +# +# @param object: Inherited from object class +# +# @var Id: To store value for Id +# @var UiName: To store value for UiName +# @var Preferred: To store value for Preferred +# @var FilePath: To store value for FilePath +# +class PlatformFlashDefinitionFileClass(object): + def __init__(self): + self.Id = '' + self.UiName = '' + self.Preferred = False + self.FilePath = '' + +## PlatformFvImageOptionClass +# +# This class defined FvImageOption item used in platform file +# +# @param object: Inherited from object class +# +# @var FvImageOptionName: To store value for FvImageOptionName +# @var FvImageOptionValues: To store value for FvImageOptionValues +# +class PlatformFvImageOptionClass(object): + def __init__(self): + self.FvImageOptionName = '' + self.FvImageOptionValues = [] + +## PlatformFvImageClass +# +# This class defined FvImage item used in platform file +# +# @param object: Inherited from object class +# +# @var Name: To store value for Name +# @var Value: To store value for Value +# @var Type: To store value for Type, selection scope is in below list +# Attributes | Options | Components | ImageName +# @var FvImageNames: To store value for FvImageNames +# @var FvImageOptions: To store value for FvImageOptions, it is a list structure as +# [ PlatformFvImageOption, ...] +# +class PlatformFvImageClass(object): + def __init__(self): + self.Name = '' + self.Value = '' + self.Type = '' + self.FvImageNames = [] + self.FvImageOptions = [] + +## PlatformFvImageNameClass +# +# This class defined FvImageName item used in platform file +# +# @param object: Inherited from object class +# +# @var Name: To store value for Name +# @var Type: To store value for Type, selection scope is in below list +# FV_MAIN | FV_MAIN_COMPACT | NV_STORAGE | FV_RECOVERY | FV_RECOVERY_FLOPPY | FV_FILE | CAPSULE_CARGO | NULL | USER_DEFINED +# @var FvImageOptions: To store value for FvImageOptions, it is a list structure as +# [ PlatformFvImageOption, ...] +# +class PlatformFvImageNameClass(object): + def __init__(self): + self.Name = '' + self.Type = '' + self.FvImageOptions = [] + +## PlatformFvImagesClass +# +# This class defined FvImages item used in platform file +# +# @param object: Inherited from object class +# +# @var FvImages: To store value for FvImages +# +class PlatformFvImagesClass(object): + def __init__(self): + self.FvImages = [] + +## PlatformAntTaskClass +# +# This class defined AntTask item used in platform file +# +# @param object: Inherited from object class +# +# @var Id: To store value for Id +# @var AntCmdOptions: To store value for AntCmdOptions +# @var FilePath: To store value for FilePath +# +class PlatformAntTaskClass(object): + def __init__(self): + self.Id = '' + self.AntCmdOptions = '' + self.FilePath = '' + +## PlatformFfsSectionClass +# +# This class defined FfsSection item used in platform file +# +# @param CommonClass: Inherited from CommonClass class +# +# @var BindingOrder: To store value for BindingOrder +# @var Compressible: To store value for Compressible +# @var SectionType: To store value for SectionType +# @var EncapsulationType: To store value for EncapsulationType +# @var ToolName: To store value for ToolName +# @var Filenames: To store value for Filenames +# @var Args: To store value for Args +# @var OutFile: To store value for OutFile +# @var OutputFileExtension: To store value for OutputFileExtension +# @var ToolNameElement: To store value for ToolNameElement +# +class PlatformFfsSectionClass(CommonClass): + def __init__(self): + CommonClass.__init__(self) + self.BindingOrder = '' + self.Compressible = '' + self.SectionType = '' + self.EncapsulationType = '' + self.ToolName = '' + self.Filenames = [] + self.Args = '' + self.OutFile = '' + self.OutputFileExtension = '' + self.ToolNameElement = '' + +## PlatformFfsSectionsClass +# +# This class defined FfsSections item used in platform file +# +# @param CommonClass: Inherited from CommonClass class +# +# @var BindingOrder: To store value for BindingOrder +# @var Compressible: To store value for Compressible +# @var SectionType: To store value for SectionType +# @var EncapsulationType: To store value for EncapsulationType +# @var ToolName: To store value for ToolName +# @var Section: To store value for Section, it is a list structure as +# [ PlatformFfsSectionClass, ... ] +# @var Sections: To store value for Sections, it is a list structure as +# [ PlatformFfsSectionsClass, ...] +# +class PlatformFfsSectionsClass(CommonClass): + def __init__(self): + CommonClass.__init__(self) + self.BindingOrder = '' + self.Compressible = '' + self.SectionType = '' + self.EncapsulationType = '' + self.ToolName = '' + self.Section = [] + self.Sections = [] + +## PlatformFfsClass +# +# This class defined Ffs item used in platform file +# +# @param object: Inherited from object class +# +# @var Attribute: To store value for Attribute, it is a set structure as +# { [(Name, PlatformFfsSectionsClass)] : Value} +# @var Sections: To store value for Sections, it is a list structure as +# [ PlatformFfsSectionsClass] +# @var ToolName: To store value for ToolName +# +class PlatformFfsClass(object): + def __init__(self): + self.Attribute = {} + self.Sections = [] + self.Key = '' + +## PlatformBuildOptionClass +# +# This class defined BuildOption item used in platform file +# +# @param object: Inherited from object class +# +# @var UserDefinedAntTasks: To store value for UserDefinedAntTasks, it is a set structure as +# { [Id] : PlatformAntTaskClass, ...} +# @var Options: To store value for Options, it is a list structure as +# [ BuildOptionClass, ...] +# @var UserExtensions: To store value for UserExtensions, it is a set structure as +# { [(UserID, Identifier)] : UserExtensionsClass, ...} +# @var FfsKeyList: To store value for FfsKeyList, it is a set structure as +# { [FfsKey]: PlatformFfsClass, ...} +# +class PlatformBuildOptionClass(object): + def __init__(self): + self.UserDefinedAntTasks = {} + self.Options = [] + self.UserExtensions = {} + self.FfsKeyList = {} + +## PlatformBuildOptionClasses +# +# This class defined BuildOption item list used in platform file +# +# @param IncludeStatementClass: Inherited from IncludeStatementClass class +# +# @var FvBinding: To store value for FvBinding +# @var FfsFileNameGuid: To store value for FfsFileNameGuid +# @var FfsFormatKey: To store value for FfsFormatKey +# @var BuildOptionList: To store value for BuildOptionList, it is a list structure as +# [ BuildOptionClass, ... ] +# +class PlatformBuildOptionClasses(IncludeStatementClass): + def __init__(self): + IncludeStatementClass.__init__(self) + self.FvBinding = '' + self.FfsFileNameGuid = '' + self.FfsFormatKey = '' + self.BuildOptionList = [] + +## PlatformLibraryClass +# +# This class defined Library item used in platform file +# +# @param CommonClass: Inherited from CommonClass class +# @param DefineClass: Inherited from DefineClass class +# @param Name: Input value for Name, default is '' +# @param FilePath: Input value for FilePath, default is '' +# +# @var Name: To store value for Name +# @var FilePath: To store value for FilePath +# @var ModuleType: To store value for ModuleType +# @var SupModuleList: To store value for SupModuleList +# @var ModuleGuid: To store value for ModuleGuid +# @var ModuleVersion: To store value for ModuleVersion +# @var PackageGuid: To store value for PackageGuid +# @var PackageVersion: To store value for PackageVersion +# +class PlatformLibraryClass(CommonClass, DefineClass): + def __init__(self, Name = '', FilePath = ''): + CommonClass.__init__(self) + DefineClass.__init__(self) + self.Name = Name + self.FilePath = FilePath + self.ModuleType = [] + self.SupModuleList = [] + self.ModuleGuid = '' + self.ModuleVersion = '' + self.PackageGuid = '' + self.PackageVersion = '' + +## PlatformLibraryClasses +# +# This class defined Library item list used in platform file +# +# @param IncludeStatementClass: Inherited from IncludeStatementClass class +# +# @var LibraryList: To store value for LibraryList, it is a list structure as +# [ PlatformLibraryClass, ... ] +# +class PlatformLibraryClasses(IncludeStatementClass): + def __init__(self): + IncludeStatementClass.__init__(self) + self.LibraryList = [] + +## PlatformModuleClass +# +# This class defined Module item used in platform file +# +# @param CommonClass: Inherited from CommonClass class +# @param DefineClass: Inherited from DefineClass class +# @param IncludeStatementClass: Inherited from IncludeStatementClass class +# +# @var Name: To store value for Name (Library name or libraryclass name or module name) +# @var FilePath: To store value for FilePath +# @var Type: To store value for Type, selection scope is in below list +# LIBRARY | LIBRARY_CLASS | MODULE +# @var ModuleType: To store value for ModuleType +# @var ExecFilePath: To store value for ExecFilePath +# @var LibraryClasses: To store value for LibraryClasses, it is a structure as +# PlatformLibraryClasses +# @var PcdBuildDefinitions: To store value for PcdBuildDefinitions, it is a list structure as +# [ PcdClass, ...] +# @var ModuleSaBuildOption: To store value for ModuleSaBuildOption, it is a structure as +# PlatformBuildOptionClasses +# @var Specifications: To store value for Specifications, it is a list structure as +# [ '', '', ...] +# +class PlatformModuleClass(CommonClass, DefineClass, IncludeStatementClass): + def __init__(self): + CommonClass.__init__(self) + DefineClass.__init__(self) + self.Name = '' + self.FilePath = '' + self.Type = '' + self.ModuleType = '' + self.ExecFilePath = '' + self.LibraryClasses = PlatformLibraryClasses() + self.PcdBuildDefinitions = [] + self.ModuleSaBuildOption = PlatformBuildOptionClasses() + self.Specifications = [] + self.SourceOverridePath = '' + +## PlatformModuleClasses +# +# This class defined Module item list used in platform file +# +# @param IncludeStatementClass: Inherited from IncludeStatementClass class +# +# @var ModuleList: To store value for ModuleList, it is a list structure as +# [ PlatformModuleClass, ... ] +# +class PlatformModuleClasses(IncludeStatementClass): + def __init__(self): + IncludeStatementClass.__init__(self) + self.ModuleList = [] + +## PlatformClass +# +# This class defined a complete platform item +# +# @param object: Inherited from object class +# +# @var Header: To store value for Header, it is a structure as +# {Arch : PlatformHeaderClass()} +# @var SkuInfos: To store value for SkuInfos, it is a structure as +# SkuInfoListClass +# @var Libraries: To store value for Libraries, it is a structure as +# PlatformLibraryClasses +# @var LibraryClasses: To store value for LibraryClasses, it is a structure as +# PlatformLibraryClasses +# @var Modules: To store value for Modules, it is a structure as +# PlatformModuleClasses +# @var FlashDefinitionFile: To store value for FlashDefinitionFile, it is a structure as +# PlatformFlashDefinitionFileClass +# @var BuildOptions: To store value for BuildOptions, it is a structure as +# PlatformBuildOptionClasses +# @var DynamicPcdBuildDefinitions: To store value for DynamicPcdBuildDefinitions, it is a list structure as +# [ PcdClass, ...] +# @var Fdf: To store value for Fdf, it is a list structure as +# [ FdfClass, ...] +# @var UserExtensions: To store value for UserExtensions, it is a list structure as +# [ UserExtensionsClass, ...] +# +class PlatformClass(object): + def __init__(self): + self.Header = {} + self.SkuInfos = SkuInfoListClass() + self.Libraries = PlatformLibraryClasses() + self.LibraryClasses = PlatformLibraryClasses() + self.Modules = PlatformModuleClasses() + self.FlashDefinitionFile = PlatformFlashDefinitionFileClass() + self.BuildOptions = PlatformBuildOptionClasses() + self.DynamicPcdBuildDefinitions = [] + self.Fdf = [] + self.UserExtensions = [] + +## +# +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +# +if __name__ == '__main__': + P = PlatformClass() diff --git a/BaseTools/Source/Python/CommonDataClass/__init__.py b/BaseTools/Source/Python/CommonDataClass/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/BaseTools/Source/Python/Ecc/C.g b/BaseTools/Source/Python/Ecc/C.g new file mode 100644 index 0000000000..6aa50460de --- /dev/null +++ b/BaseTools/Source/Python/Ecc/C.g @@ -0,0 +1,626 @@ + +grammar C; +options { + language=Python; + backtrack=true; + memoize=true; + k=2; +} + +@header { + import CodeFragment + import FileProfile +} + +@members { + + def printTokenInfo(self, line, offset, tokenText): + print str(line)+ ',' + str(offset) + ':' + str(tokenText) + + def StorePredicateExpression(self, StartLine, StartOffset, EndLine, EndOffset, Text): + PredExp = CodeFragment.PredicateExpression(Text, (StartLine, StartOffset), (EndLine, EndOffset)) + FileProfile.PredicateExpressionList.append(PredExp) + + def StoreEnumerationDefinition(self, StartLine, StartOffset, EndLine, EndOffset, Text): + EnumDef = CodeFragment.EnumerationDefinition(Text, (StartLine, StartOffset), (EndLine, EndOffset)) + FileProfile.EnumerationDefinitionList.append(EnumDef) + + def StoreStructUnionDefinition(self, StartLine, StartOffset, EndLine, EndOffset, Text): + SUDef = CodeFragment.StructUnionDefinition(Text, (StartLine, StartOffset), (EndLine, EndOffset)) + FileProfile.StructUnionDefinitionList.append(SUDef) + + def StoreTypedefDefinition(self, StartLine, StartOffset, EndLine, EndOffset, FromText, ToText): + Tdef = CodeFragment.TypedefDefinition(FromText, ToText, (StartLine, StartOffset), (EndLine, EndOffset)) + FileProfile.TypedefDefinitionList.append(Tdef) + + def StoreFunctionDefinition(self, StartLine, StartOffset, EndLine, EndOffset, ModifierText, DeclText, LeftBraceLine, LeftBraceOffset, DeclLine, DeclOffset): + FuncDef = CodeFragment.FunctionDefinition(ModifierText, DeclText, (StartLine, StartOffset), (EndLine, EndOffset), (LeftBraceLine, LeftBraceOffset), (DeclLine, DeclOffset)) + FileProfile.FunctionDefinitionList.append(FuncDef) + + def StoreVariableDeclaration(self, StartLine, StartOffset, EndLine, EndOffset, ModifierText, DeclText): + VarDecl = CodeFragment.VariableDeclaration(ModifierText, DeclText, (StartLine, StartOffset), (EndLine, EndOffset)) + FileProfile.VariableDeclarationList.append(VarDecl) + + def StoreFunctionCalling(self, StartLine, StartOffset, EndLine, EndOffset, FuncName, ParamList): + FuncCall = CodeFragment.FunctionCalling(FuncName, ParamList, (StartLine, StartOffset), (EndLine, EndOffset)) + FileProfile.FunctionCallingList.append(FuncCall) + +} + +translation_unit + : external_declaration* + ; + + +/*function_declaration +@after{ + print $function_declaration.text +} + : declaration_specifiers IDENTIFIER '(' parameter_list ')' ';' + ; +*/ +external_declaration +options {k=1;} +/*@after{ + print $external_declaration.text +}*/ + : ( declaration_specifiers? declarator declaration* '{' )=> function_definition + | declaration + | macro_statement (';')? + ; + + + +function_definition +scope { + ModifierText; + DeclText; + LBLine; + LBOffset; + DeclLine; + DeclOffset; +} +@init { + $function_definition::ModifierText = ''; + $function_definition::DeclText = ''; + $function_definition::LBLine = 0; + $function_definition::LBOffset = 0; + $function_definition::DeclLine = 0; + $function_definition::DeclOffset = 0; +} +@after{ + self.StoreFunctionDefinition($function_definition.start.line, $function_definition.start.charPositionInLine, $function_definition.stop.line, $function_definition.stop.charPositionInLine, $function_definition::ModifierText, $function_definition::DeclText, $function_definition::LBLine, $function_definition::LBOffset, $function_definition::DeclLine, $function_definition::DeclOffset) +} + : d=declaration_specifiers? declarator + ( declaration+ a=compound_statement // K&R style + | b=compound_statement // ANSI style + ) { + if d != None: + $function_definition::ModifierText = $declaration_specifiers.text + else: + $function_definition::ModifierText = '' + $function_definition::DeclText = $declarator.text + $function_definition::DeclLine = $declarator.start.line + $function_definition::DeclOffset = $declarator.start.charPositionInLine + if a != None: + $function_definition::LBLine = $a.start.line + $function_definition::LBOffset = $a.start.charPositionInLine + else: + $function_definition::LBLine = $b.start.line + $function_definition::LBOffset = $b.start.charPositionInLine + } + ; + +declaration + : a='typedef' b=declaration_specifiers? + c=init_declarator_list d=';' + { + if b != None: + self.StoreTypedefDefinition($a.line, $a.charPositionInLine, $d.line, $d.charPositionInLine, $b.text, $c.text) + else: + self.StoreTypedefDefinition($a.line, $a.charPositionInLine, $d.line, $d.charPositionInLine, '', $c.text) + } + | s=declaration_specifiers t=init_declarator_list? e=';' + { + if t != None: + self.StoreVariableDeclaration($s.start.line, $s.start.charPositionInLine, $t.start.line, $t.start.charPositionInLine, $s.text, $t.text) + } + ; + +declaration_specifiers + : ( storage_class_specifier + | type_specifier + | type_qualifier + )+ + ; + +init_declarator_list + : init_declarator (',' init_declarator)* + ; + +init_declarator + : declarator ('=' initializer)? + ; + +storage_class_specifier + : 'extern' + | 'static' + | 'auto' + | 'register' + | 'STATIC' + ; + +type_specifier + : 'void' + | 'char' + | 'short' + | 'int' + | 'long' + | 'float' + | 'double' + | 'signed' + | 'unsigned' + | s=struct_or_union_specifier + { + if s.stop != None: + self.StoreStructUnionDefinition($s.start.line, $s.start.charPositionInLine, $s.stop.line, $s.stop.charPositionInLine, $s.text) + } + | e=enum_specifier + { + if e.stop != None: + self.StoreEnumerationDefinition($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text) + } + | (IDENTIFIER type_qualifier* declarator)=> type_id + ; + +type_id + : IDENTIFIER + //{self.printTokenInfo($a.line, $a.pos, $a.text)} + ; + +struct_or_union_specifier +options {k=3;} + : struct_or_union IDENTIFIER? '{' struct_declaration_list '}' + | struct_or_union IDENTIFIER + ; + +struct_or_union + : 'struct' + | 'union' + ; + +struct_declaration_list + : struct_declaration+ + ; + +struct_declaration + : specifier_qualifier_list struct_declarator_list ';' + ; + +specifier_qualifier_list + : ( type_qualifier | type_specifier )+ + ; + +struct_declarator_list + : struct_declarator (',' struct_declarator)* + ; + +struct_declarator + : declarator (':' constant_expression)? + | ':' constant_expression + ; + +enum_specifier +options {k=3;} + : 'enum' '{' enumerator_list ','? '}' + | 'enum' IDENTIFIER '{' enumerator_list ','? '}' + | 'enum' IDENTIFIER + ; + +enumerator_list + : enumerator (',' enumerator)* + ; + +enumerator + : IDENTIFIER ('=' constant_expression)? + ; + +type_qualifier + : 'const' + | 'volatile' + | 'IN' + | 'OUT' + | 'OPTIONAL' + | 'CONST' + | 'UNALIGNED' + | 'VOLATILE' + | 'GLOBAL_REMOVE_IF_UNREFERENCED' + | 'EFIAPI' + | 'EFI_BOOTSERVICE' + | 'EFI_RUNTIMESERVICE' + ; + +declarator + : pointer? ('EFIAPI')? ('EFI_BOOTSERVICE')? ('EFI_RUNTIMESERVICE')? direct_declarator +// | ('EFIAPI')? ('EFI_BOOTSERVICE')? ('EFI_RUNTIMESERVICE')? pointer? direct_declarator + | pointer + ; + +direct_declarator + : IDENTIFIER declarator_suffix* + | '(' ('EFIAPI')? declarator ')' declarator_suffix+ + ; + +declarator_suffix + : '[' constant_expression ']' + | '[' ']' + | '(' parameter_type_list ')' + | '(' identifier_list ')' + | '(' ')' + ; + +pointer + : '*' type_qualifier+ pointer? + | '*' pointer + | '*' + ; + +parameter_type_list + : parameter_list (',' ('OPTIONAL')? '...')? + ; + +parameter_list + : parameter_declaration (',' ('OPTIONAL')? parameter_declaration)* + ; + +parameter_declaration + : declaration_specifiers (declarator|abstract_declarator)* ('OPTIONAL')? + //accomerdate user-defined type only, no declarator follow. + | pointer* IDENTIFIER + ; + +identifier_list + : IDENTIFIER + (',' IDENTIFIER)* + ; + +type_name + : specifier_qualifier_list abstract_declarator? + | type_id + ; + +abstract_declarator + : pointer direct_abstract_declarator? + | direct_abstract_declarator + ; + +direct_abstract_declarator + : ( '(' abstract_declarator ')' | abstract_declarator_suffix ) abstract_declarator_suffix* + ; + +abstract_declarator_suffix + : '[' ']' + | '[' constant_expression ']' + | '(' ')' + | '(' parameter_type_list ')' + ; + +initializer + + : assignment_expression + | '{' initializer_list ','? '}' + ; + +initializer_list + : initializer (',' initializer )* + ; + +// E x p r e s s i o n s + +argument_expression_list + : assignment_expression ('OPTIONAL')? (',' assignment_expression ('OPTIONAL')?)* + ; + +additive_expression + : (multiplicative_expression) ('+' multiplicative_expression | '-' multiplicative_expression)* + ; + +multiplicative_expression + : (cast_expression) ('*' cast_expression | '/' cast_expression | '%' cast_expression)* + ; + +cast_expression + : '(' type_name ')' cast_expression + | unary_expression + ; + +unary_expression + : postfix_expression + | '++' unary_expression + | '--' unary_expression + | unary_operator cast_expression + | 'sizeof' unary_expression + | 'sizeof' '(' type_name ')' + ; + +postfix_expression +scope { + FuncCallText; +} +@init { + $postfix_expression::FuncCallText = ''; +} + : p=primary_expression {$postfix_expression::FuncCallText += $p.text} + ( '[' expression ']' + | '(' a=')'{self.StoreFunctionCalling($p.start.line, $p.start.charPositionInLine, $a.line, $a.charPositionInLine, $postfix_expression::FuncCallText, '')} + | '(' c=argument_expression_list b=')' {self.StoreFunctionCalling($p.start.line, $p.start.charPositionInLine, $b.line, $b.charPositionInLine, $postfix_expression::FuncCallText, $c.text)} + | '(' macro_parameter_list ')' + | '.' x=IDENTIFIER {$postfix_expression::FuncCallText += '.' + $x.text} + | '*' y=IDENTIFIER {$postfix_expression::FuncCallText = $y.text} + | '->' z=IDENTIFIER {$postfix_expression::FuncCallText += '->' + $z.text} + | '++' + | '--' + )* + ; + +macro_parameter_list + : parameter_declaration (',' parameter_declaration)* + ; + +unary_operator + : '&' + | '*' + | '+' + | '-' + | '~' + | '!' + ; + +primary_expression + : IDENTIFIER + | constant + | '(' expression ')' + ; + +constant + : HEX_LITERAL + | OCTAL_LITERAL + | DECIMAL_LITERAL + | CHARACTER_LITERAL + | (IDENTIFIER* STRING_LITERAL+)+ IDENTIFIER* + | FLOATING_POINT_LITERAL + ; + +///// + +expression + : assignment_expression (',' assignment_expression)* + ; + +constant_expression + : conditional_expression + ; + +assignment_expression + : lvalue assignment_operator assignment_expression + | conditional_expression + ; + +lvalue + : unary_expression + ; + +assignment_operator + : '=' + | '*=' + | '/=' + | '%=' + | '+=' + | '-=' + | '<<=' + | '>>=' + | '&=' + | '^=' + | '|=' + ; + +conditional_expression + : e=logical_or_expression ('?' expression ':' conditional_expression {self.StorePredicateExpression($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)})? + ; + +logical_or_expression + : logical_and_expression ('||' logical_and_expression)* + ; + +logical_and_expression + : inclusive_or_expression ('&&' inclusive_or_expression)* + ; + +inclusive_or_expression + : exclusive_or_expression ('|' exclusive_or_expression)* + ; + +exclusive_or_expression + : and_expression ('^' and_expression)* + ; + +and_expression + : equality_expression ('&' equality_expression)* + ; +equality_expression + : relational_expression (('=='|'!=') relational_expression )* + ; + +relational_expression + : shift_expression (('<'|'>'|'<='|'>=') shift_expression)* + ; + +shift_expression + : additive_expression (('<<'|'>>') additive_expression)* + ; + +// S t a t e m e n t s + +statement + : labeled_statement + | compound_statement + | expression_statement + | selection_statement + | iteration_statement + | jump_statement + | macro_statement + | asm2_statement + | asm1_statement + | asm_statement + | declaration + ; + +asm2_statement + : '__asm__'? IDENTIFIER '(' (~(';'))* ')' ';' + ; + +asm1_statement + : '_asm' '{' (~('}'))* '}' + ; + +asm_statement + : '__asm' '{' (~('}'))* '}' + ; + +macro_statement + : IDENTIFIER '(' declaration* statement_list? expression? ')' + ; + +labeled_statement + : IDENTIFIER ':' statement + | 'case' constant_expression ':' statement + | 'default' ':' statement + ; + +compound_statement + : '{' declaration* statement_list? '}' + ; + +statement_list + : statement+ + ; + +expression_statement + : ';' + | expression ';' + ; + +selection_statement + : 'if' '(' e=expression ')' {self.StorePredicateExpression($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)} statement (options {k=1; backtrack=false;}:'else' statement)? + | 'switch' '(' expression ')' statement + ; + +iteration_statement + : 'while' '(' e=expression ')' statement {self.StorePredicateExpression($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)} + | 'do' statement 'while' '(' e=expression ')' ';' {self.StorePredicateExpression($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)} + | 'for' '(' expression_statement e=expression_statement expression? ')' statement {self.StorePredicateExpression($e.start.line, $e.start.charPositionInLine, $e.stop.line, $e.stop.charPositionInLine, $e.text)} + ; + +jump_statement + : 'goto' IDENTIFIER ';' + | 'continue' ';' + | 'break' ';' + | 'return' ';' + | 'return' expression ';' + ; + +IDENTIFIER + : LETTER (LETTER|'0'..'9')* + ; + +fragment +LETTER + : '$' + | 'A'..'Z' + | 'a'..'z' + | '_' + ; + +CHARACTER_LITERAL + : ('L')? '\'' ( EscapeSequence | ~('\''|'\\') ) '\'' + ; + +STRING_LITERAL + : ('L')? '"' ( EscapeSequence | ~('\\'|'"') )* '"' + ; + +HEX_LITERAL : '0' ('x'|'X') HexDigit+ IntegerTypeSuffix? ; + +DECIMAL_LITERAL : ('0' | '1'..'9' '0'..'9'*) IntegerTypeSuffix? ; + +OCTAL_LITERAL : '0' ('0'..'7')+ IntegerTypeSuffix? ; + +fragment +HexDigit : ('0'..'9'|'a'..'f'|'A'..'F') ; + +fragment +IntegerTypeSuffix + : ('u'|'U') + | ('l'|'L') + | ('u'|'U') ('l'|'L') + | ('u'|'U') ('l'|'L') ('l'|'L') + ; + +FLOATING_POINT_LITERAL + : ('0'..'9')+ '.' ('0'..'9')* Exponent? FloatTypeSuffix? + | '.' ('0'..'9')+ Exponent? FloatTypeSuffix? + | ('0'..'9')+ Exponent FloatTypeSuffix? + | ('0'..'9')+ Exponent? FloatTypeSuffix + ; + +fragment +Exponent : ('e'|'E') ('+'|'-')? ('0'..'9')+ ; + +fragment +FloatTypeSuffix : ('f'|'F'|'d'|'D') ; + +fragment +EscapeSequence + : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') + | OctalEscape + ; + +fragment +OctalEscape + : '\\' ('0'..'3') ('0'..'7') ('0'..'7') + | '\\' ('0'..'7') ('0'..'7') + | '\\' ('0'..'7') + ; + +fragment +UnicodeEscape + : '\\' 'u' HexDigit HexDigit HexDigit HexDigit + ; + +WS : (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;} + ; + +// ingore '\' of line concatenation +BS : ('\\') {$channel=HIDDEN;} + ; + +// ingore function modifiers +//FUNC_MODIFIERS : 'EFIAPI' {$channel=HIDDEN;} +// ; + +UnicodeVocabulary + : '\u0003'..'\uFFFE' + ; +COMMENT + : '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;} + ; + + +LINE_COMMENT + : '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;} + ; + +// ignore #line info for now +LINE_COMMAND + : '#' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;} + ; diff --git a/BaseTools/Source/Python/Ecc/CLexer.py b/BaseTools/Source/Python/Ecc/CLexer.py new file mode 100644 index 0000000000..cc437e0821 --- /dev/null +++ b/BaseTools/Source/Python/Ecc/CLexer.py @@ -0,0 +1,4887 @@ +# $ANTLR 3.0.1 C.g 2009-02-16 16:02:51 + +from antlr3 import * +from antlr3.compat import set, frozenset + + +# for convenience in actions +HIDDEN = BaseRecognizer.HIDDEN + +# token types +T29=29 +HexDigit=13 +T70=70 +T74=74 +T85=85 +T102=102 +T114=114 +T103=103 +STRING_LITERAL=9 +T32=32 +T81=81 +T41=41 +FloatTypeSuffix=16 +T113=113 +T62=62 +T109=109 +DECIMAL_LITERAL=7 +IntegerTypeSuffix=14 +T68=68 +T73=73 +T84=84 +T33=33 +UnicodeVocabulary=21 +T78=78 +T115=115 +WS=19 +LINE_COMMAND=24 +T42=42 +T96=96 +T71=71 +LINE_COMMENT=23 +T72=72 +T94=94 +FLOATING_POINT_LITERAL=10 +T76=76 +UnicodeEscape=18 +T75=75 +T89=89 +T67=67 +T31=31 +T60=60 +T82=82 +T100=100 +T49=49 +IDENTIFIER=4 +T30=30 +CHARACTER_LITERAL=8 +T79=79 +T36=36 +T58=58 +T93=93 +T35=35 +T107=107 +OCTAL_LITERAL=6 +T83=83 +T61=61 +HEX_LITERAL=5 +T45=45 +T34=34 +T101=101 +T64=64 +T25=25 +T91=91 +T105=105 +T37=37 +T86=86 +T116=116 +EscapeSequence=12 +T26=26 +T51=51 +T111=111 +T46=46 +T77=77 +T38=38 +T106=106 +T112=112 +T69=69 +T39=39 +T44=44 +T55=55 +LETTER=11 +Exponent=15 +T95=95 +T50=50 +T110=110 +T108=108 +BS=20 +T92=92 +T43=43 +T28=28 +T40=40 +T66=66 +COMMENT=22 +T88=88 +T63=63 +T57=57 +T65=65 +T98=98 +T56=56 +T87=87 +T80=80 +T59=59 +T97=97 +T48=48 +T54=54 +EOF=-1 +T104=104 +T47=47 +Tokens=117 +T53=53 +OctalEscape=17 +T99=99 +T27=27 +T52=52 +T90=90 + +class CLexer(Lexer): + + grammarFileName = "C.g" + + def __init__(self, input=None): + Lexer.__init__(self, input) + self.dfa25 = self.DFA25( + self, 25, + eot = self.DFA25_eot, + eof = self.DFA25_eof, + min = self.DFA25_min, + max = self.DFA25_max, + accept = self.DFA25_accept, + special = self.DFA25_special, + transition = self.DFA25_transition + ) + self.dfa35 = self.DFA35( + self, 35, + eot = self.DFA35_eot, + eof = self.DFA35_eof, + min = self.DFA35_min, + max = self.DFA35_max, + accept = self.DFA35_accept, + special = self.DFA35_special, + transition = self.DFA35_transition + ) + + + + + + + # $ANTLR start T25 + def mT25(self, ): + + try: + self.type = T25 + + # C.g:7:5: ( ';' ) + # C.g:7:7: ';' + self.match(u';') + + + + + + finally: + + pass + + # $ANTLR end T25 + + + + # $ANTLR start T26 + def mT26(self, ): + + try: + self.type = T26 + + # C.g:8:5: ( 'typedef' ) + # C.g:8:7: 'typedef' + self.match("typedef") + + + + + + + finally: + + pass + + # $ANTLR end T26 + + + + # $ANTLR start T27 + def mT27(self, ): + + try: + self.type = T27 + + # C.g:9:5: ( ',' ) + # C.g:9:7: ',' + self.match(u',') + + + + + + finally: + + pass + + # $ANTLR end T27 + + + + # $ANTLR start T28 + def mT28(self, ): + + try: + self.type = T28 + + # C.g:10:5: ( '=' ) + # C.g:10:7: '=' + self.match(u'=') + + + + + + finally: + + pass + + # $ANTLR end T28 + + + + # $ANTLR start T29 + def mT29(self, ): + + try: + self.type = T29 + + # C.g:11:5: ( 'extern' ) + # C.g:11:7: 'extern' + self.match("extern") + + + + + + + finally: + + pass + + # $ANTLR end T29 + + + + # $ANTLR start T30 + def mT30(self, ): + + try: + self.type = T30 + + # C.g:12:5: ( 'static' ) + # C.g:12:7: 'static' + self.match("static") + + + + + + + finally: + + pass + + # $ANTLR end T30 + + + + # $ANTLR start T31 + def mT31(self, ): + + try: + self.type = T31 + + # C.g:13:5: ( 'auto' ) + # C.g:13:7: 'auto' + self.match("auto") + + + + + + + finally: + + pass + + # $ANTLR end T31 + + + + # $ANTLR start T32 + def mT32(self, ): + + try: + self.type = T32 + + # C.g:14:5: ( 'register' ) + # C.g:14:7: 'register' + self.match("register") + + + + + + + finally: + + pass + + # $ANTLR end T32 + + + + # $ANTLR start T33 + def mT33(self, ): + + try: + self.type = T33 + + # C.g:15:5: ( 'STATIC' ) + # C.g:15:7: 'STATIC' + self.match("STATIC") + + + + + + + finally: + + pass + + # $ANTLR end T33 + + + + # $ANTLR start T34 + def mT34(self, ): + + try: + self.type = T34 + + # C.g:16:5: ( 'void' ) + # C.g:16:7: 'void' + self.match("void") + + + + + + + finally: + + pass + + # $ANTLR end T34 + + + + # $ANTLR start T35 + def mT35(self, ): + + try: + self.type = T35 + + # C.g:17:5: ( 'char' ) + # C.g:17:7: 'char' + self.match("char") + + + + + + + finally: + + pass + + # $ANTLR end T35 + + + + # $ANTLR start T36 + def mT36(self, ): + + try: + self.type = T36 + + # C.g:18:5: ( 'short' ) + # C.g:18:7: 'short' + self.match("short") + + + + + + + finally: + + pass + + # $ANTLR end T36 + + + + # $ANTLR start T37 + def mT37(self, ): + + try: + self.type = T37 + + # C.g:19:5: ( 'int' ) + # C.g:19:7: 'int' + self.match("int") + + + + + + + finally: + + pass + + # $ANTLR end T37 + + + + # $ANTLR start T38 + def mT38(self, ): + + try: + self.type = T38 + + # C.g:20:5: ( 'long' ) + # C.g:20:7: 'long' + self.match("long") + + + + + + + finally: + + pass + + # $ANTLR end T38 + + + + # $ANTLR start T39 + def mT39(self, ): + + try: + self.type = T39 + + # C.g:21:5: ( 'float' ) + # C.g:21:7: 'float' + self.match("float") + + + + + + + finally: + + pass + + # $ANTLR end T39 + + + + # $ANTLR start T40 + def mT40(self, ): + + try: + self.type = T40 + + # C.g:22:5: ( 'double' ) + # C.g:22:7: 'double' + self.match("double") + + + + + + + finally: + + pass + + # $ANTLR end T40 + + + + # $ANTLR start T41 + def mT41(self, ): + + try: + self.type = T41 + + # C.g:23:5: ( 'signed' ) + # C.g:23:7: 'signed' + self.match("signed") + + + + + + + finally: + + pass + + # $ANTLR end T41 + + + + # $ANTLR start T42 + def mT42(self, ): + + try: + self.type = T42 + + # C.g:24:5: ( 'unsigned' ) + # C.g:24:7: 'unsigned' + self.match("unsigned") + + + + + + + finally: + + pass + + # $ANTLR end T42 + + + + # $ANTLR start T43 + def mT43(self, ): + + try: + self.type = T43 + + # C.g:25:5: ( '{' ) + # C.g:25:7: '{' + self.match(u'{') + + + + + + finally: + + pass + + # $ANTLR end T43 + + + + # $ANTLR start T44 + def mT44(self, ): + + try: + self.type = T44 + + # C.g:26:5: ( '}' ) + # C.g:26:7: '}' + self.match(u'}') + + + + + + finally: + + pass + + # $ANTLR end T44 + + + + # $ANTLR start T45 + def mT45(self, ): + + try: + self.type = T45 + + # C.g:27:5: ( 'struct' ) + # C.g:27:7: 'struct' + self.match("struct") + + + + + + + finally: + + pass + + # $ANTLR end T45 + + + + # $ANTLR start T46 + def mT46(self, ): + + try: + self.type = T46 + + # C.g:28:5: ( 'union' ) + # C.g:28:7: 'union' + self.match("union") + + + + + + + finally: + + pass + + # $ANTLR end T46 + + + + # $ANTLR start T47 + def mT47(self, ): + + try: + self.type = T47 + + # C.g:29:5: ( ':' ) + # C.g:29:7: ':' + self.match(u':') + + + + + + finally: + + pass + + # $ANTLR end T47 + + + + # $ANTLR start T48 + def mT48(self, ): + + try: + self.type = T48 + + # C.g:30:5: ( 'enum' ) + # C.g:30:7: 'enum' + self.match("enum") + + + + + + + finally: + + pass + + # $ANTLR end T48 + + + + # $ANTLR start T49 + def mT49(self, ): + + try: + self.type = T49 + + # C.g:31:5: ( 'const' ) + # C.g:31:7: 'const' + self.match("const") + + + + + + + finally: + + pass + + # $ANTLR end T49 + + + + # $ANTLR start T50 + def mT50(self, ): + + try: + self.type = T50 + + # C.g:32:5: ( 'volatile' ) + # C.g:32:7: 'volatile' + self.match("volatile") + + + + + + + finally: + + pass + + # $ANTLR end T50 + + + + # $ANTLR start T51 + def mT51(self, ): + + try: + self.type = T51 + + # C.g:33:5: ( 'IN' ) + # C.g:33:7: 'IN' + self.match("IN") + + + + + + + finally: + + pass + + # $ANTLR end T51 + + + + # $ANTLR start T52 + def mT52(self, ): + + try: + self.type = T52 + + # C.g:34:5: ( 'OUT' ) + # C.g:34:7: 'OUT' + self.match("OUT") + + + + + + + finally: + + pass + + # $ANTLR end T52 + + + + # $ANTLR start T53 + def mT53(self, ): + + try: + self.type = T53 + + # C.g:35:5: ( 'OPTIONAL' ) + # C.g:35:7: 'OPTIONAL' + self.match("OPTIONAL") + + + + + + + finally: + + pass + + # $ANTLR end T53 + + + + # $ANTLR start T54 + def mT54(self, ): + + try: + self.type = T54 + + # C.g:36:5: ( 'CONST' ) + # C.g:36:7: 'CONST' + self.match("CONST") + + + + + + + finally: + + pass + + # $ANTLR end T54 + + + + # $ANTLR start T55 + def mT55(self, ): + + try: + self.type = T55 + + # C.g:37:5: ( 'UNALIGNED' ) + # C.g:37:7: 'UNALIGNED' + self.match("UNALIGNED") + + + + + + + finally: + + pass + + # $ANTLR end T55 + + + + # $ANTLR start T56 + def mT56(self, ): + + try: + self.type = T56 + + # C.g:38:5: ( 'VOLATILE' ) + # C.g:38:7: 'VOLATILE' + self.match("VOLATILE") + + + + + + + finally: + + pass + + # $ANTLR end T56 + + + + # $ANTLR start T57 + def mT57(self, ): + + try: + self.type = T57 + + # C.g:39:5: ( 'GLOBAL_REMOVE_IF_UNREFERENCED' ) + # C.g:39:7: 'GLOBAL_REMOVE_IF_UNREFERENCED' + self.match("GLOBAL_REMOVE_IF_UNREFERENCED") + + + + + + + finally: + + pass + + # $ANTLR end T57 + + + + # $ANTLR start T58 + def mT58(self, ): + + try: + self.type = T58 + + # C.g:40:5: ( 'EFIAPI' ) + # C.g:40:7: 'EFIAPI' + self.match("EFIAPI") + + + + + + + finally: + + pass + + # $ANTLR end T58 + + + + # $ANTLR start T59 + def mT59(self, ): + + try: + self.type = T59 + + # C.g:41:5: ( 'EFI_BOOTSERVICE' ) + # C.g:41:7: 'EFI_BOOTSERVICE' + self.match("EFI_BOOTSERVICE") + + + + + + + finally: + + pass + + # $ANTLR end T59 + + + + # $ANTLR start T60 + def mT60(self, ): + + try: + self.type = T60 + + # C.g:42:5: ( 'EFI_RUNTIMESERVICE' ) + # C.g:42:7: 'EFI_RUNTIMESERVICE' + self.match("EFI_RUNTIMESERVICE") + + + + + + + finally: + + pass + + # $ANTLR end T60 + + + + # $ANTLR start T61 + def mT61(self, ): + + try: + self.type = T61 + + # C.g:43:5: ( '(' ) + # C.g:43:7: '(' + self.match(u'(') + + + + + + finally: + + pass + + # $ANTLR end T61 + + + + # $ANTLR start T62 + def mT62(self, ): + + try: + self.type = T62 + + # C.g:44:5: ( ')' ) + # C.g:44:7: ')' + self.match(u')') + + + + + + finally: + + pass + + # $ANTLR end T62 + + + + # $ANTLR start T63 + def mT63(self, ): + + try: + self.type = T63 + + # C.g:45:5: ( '[' ) + # C.g:45:7: '[' + self.match(u'[') + + + + + + finally: + + pass + + # $ANTLR end T63 + + + + # $ANTLR start T64 + def mT64(self, ): + + try: + self.type = T64 + + # C.g:46:5: ( ']' ) + # C.g:46:7: ']' + self.match(u']') + + + + + + finally: + + pass + + # $ANTLR end T64 + + + + # $ANTLR start T65 + def mT65(self, ): + + try: + self.type = T65 + + # C.g:47:5: ( '*' ) + # C.g:47:7: '*' + self.match(u'*') + + + + + + finally: + + pass + + # $ANTLR end T65 + + + + # $ANTLR start T66 + def mT66(self, ): + + try: + self.type = T66 + + # C.g:48:5: ( '...' ) + # C.g:48:7: '...' + self.match("...") + + + + + + + finally: + + pass + + # $ANTLR end T66 + + + + # $ANTLR start T67 + def mT67(self, ): + + try: + self.type = T67 + + # C.g:49:5: ( '+' ) + # C.g:49:7: '+' + self.match(u'+') + + + + + + finally: + + pass + + # $ANTLR end T67 + + + + # $ANTLR start T68 + def mT68(self, ): + + try: + self.type = T68 + + # C.g:50:5: ( '-' ) + # C.g:50:7: '-' + self.match(u'-') + + + + + + finally: + + pass + + # $ANTLR end T68 + + + + # $ANTLR start T69 + def mT69(self, ): + + try: + self.type = T69 + + # C.g:51:5: ( '/' ) + # C.g:51:7: '/' + self.match(u'/') + + + + + + finally: + + pass + + # $ANTLR end T69 + + + + # $ANTLR start T70 + def mT70(self, ): + + try: + self.type = T70 + + # C.g:52:5: ( '%' ) + # C.g:52:7: '%' + self.match(u'%') + + + + + + finally: + + pass + + # $ANTLR end T70 + + + + # $ANTLR start T71 + def mT71(self, ): + + try: + self.type = T71 + + # C.g:53:5: ( '++' ) + # C.g:53:7: '++' + self.match("++") + + + + + + + finally: + + pass + + # $ANTLR end T71 + + + + # $ANTLR start T72 + def mT72(self, ): + + try: + self.type = T72 + + # C.g:54:5: ( '--' ) + # C.g:54:7: '--' + self.match("--") + + + + + + + finally: + + pass + + # $ANTLR end T72 + + + + # $ANTLR start T73 + def mT73(self, ): + + try: + self.type = T73 + + # C.g:55:5: ( 'sizeof' ) + # C.g:55:7: 'sizeof' + self.match("sizeof") + + + + + + + finally: + + pass + + # $ANTLR end T73 + + + + # $ANTLR start T74 + def mT74(self, ): + + try: + self.type = T74 + + # C.g:56:5: ( '.' ) + # C.g:56:7: '.' + self.match(u'.') + + + + + + finally: + + pass + + # $ANTLR end T74 + + + + # $ANTLR start T75 + def mT75(self, ): + + try: + self.type = T75 + + # C.g:57:5: ( '->' ) + # C.g:57:7: '->' + self.match("->") + + + + + + + finally: + + pass + + # $ANTLR end T75 + + + + # $ANTLR start T76 + def mT76(self, ): + + try: + self.type = T76 + + # C.g:58:5: ( '&' ) + # C.g:58:7: '&' + self.match(u'&') + + + + + + finally: + + pass + + # $ANTLR end T76 + + + + # $ANTLR start T77 + def mT77(self, ): + + try: + self.type = T77 + + # C.g:59:5: ( '~' ) + # C.g:59:7: '~' + self.match(u'~') + + + + + + finally: + + pass + + # $ANTLR end T77 + + + + # $ANTLR start T78 + def mT78(self, ): + + try: + self.type = T78 + + # C.g:60:5: ( '!' ) + # C.g:60:7: '!' + self.match(u'!') + + + + + + finally: + + pass + + # $ANTLR end T78 + + + + # $ANTLR start T79 + def mT79(self, ): + + try: + self.type = T79 + + # C.g:61:5: ( '*=' ) + # C.g:61:7: '*=' + self.match("*=") + + + + + + + finally: + + pass + + # $ANTLR end T79 + + + + # $ANTLR start T80 + def mT80(self, ): + + try: + self.type = T80 + + # C.g:62:5: ( '/=' ) + # C.g:62:7: '/=' + self.match("/=") + + + + + + + finally: + + pass + + # $ANTLR end T80 + + + + # $ANTLR start T81 + def mT81(self, ): + + try: + self.type = T81 + + # C.g:63:5: ( '%=' ) + # C.g:63:7: '%=' + self.match("%=") + + + + + + + finally: + + pass + + # $ANTLR end T81 + + + + # $ANTLR start T82 + def mT82(self, ): + + try: + self.type = T82 + + # C.g:64:5: ( '+=' ) + # C.g:64:7: '+=' + self.match("+=") + + + + + + + finally: + + pass + + # $ANTLR end T82 + + + + # $ANTLR start T83 + def mT83(self, ): + + try: + self.type = T83 + + # C.g:65:5: ( '-=' ) + # C.g:65:7: '-=' + self.match("-=") + + + + + + + finally: + + pass + + # $ANTLR end T83 + + + + # $ANTLR start T84 + def mT84(self, ): + + try: + self.type = T84 + + # C.g:66:5: ( '<<=' ) + # C.g:66:7: '<<=' + self.match("<<=") + + + + + + + finally: + + pass + + # $ANTLR end T84 + + + + # $ANTLR start T85 + def mT85(self, ): + + try: + self.type = T85 + + # C.g:67:5: ( '>>=' ) + # C.g:67:7: '>>=' + self.match(">>=") + + + + + + + finally: + + pass + + # $ANTLR end T85 + + + + # $ANTLR start T86 + def mT86(self, ): + + try: + self.type = T86 + + # C.g:68:5: ( '&=' ) + # C.g:68:7: '&=' + self.match("&=") + + + + + + + finally: + + pass + + # $ANTLR end T86 + + + + # $ANTLR start T87 + def mT87(self, ): + + try: + self.type = T87 + + # C.g:69:5: ( '^=' ) + # C.g:69:7: '^=' + self.match("^=") + + + + + + + finally: + + pass + + # $ANTLR end T87 + + + + # $ANTLR start T88 + def mT88(self, ): + + try: + self.type = T88 + + # C.g:70:5: ( '|=' ) + # C.g:70:7: '|=' + self.match("|=") + + + + + + + finally: + + pass + + # $ANTLR end T88 + + + + # $ANTLR start T89 + def mT89(self, ): + + try: + self.type = T89 + + # C.g:71:5: ( '?' ) + # C.g:71:7: '?' + self.match(u'?') + + + + + + finally: + + pass + + # $ANTLR end T89 + + + + # $ANTLR start T90 + def mT90(self, ): + + try: + self.type = T90 + + # C.g:72:5: ( '||' ) + # C.g:72:7: '||' + self.match("||") + + + + + + + finally: + + pass + + # $ANTLR end T90 + + + + # $ANTLR start T91 + def mT91(self, ): + + try: + self.type = T91 + + # C.g:73:5: ( '&&' ) + # C.g:73:7: '&&' + self.match("&&") + + + + + + + finally: + + pass + + # $ANTLR end T91 + + + + # $ANTLR start T92 + def mT92(self, ): + + try: + self.type = T92 + + # C.g:74:5: ( '|' ) + # C.g:74:7: '|' + self.match(u'|') + + + + + + finally: + + pass + + # $ANTLR end T92 + + + + # $ANTLR start T93 + def mT93(self, ): + + try: + self.type = T93 + + # C.g:75:5: ( '^' ) + # C.g:75:7: '^' + self.match(u'^') + + + + + + finally: + + pass + + # $ANTLR end T93 + + + + # $ANTLR start T94 + def mT94(self, ): + + try: + self.type = T94 + + # C.g:76:5: ( '==' ) + # C.g:76:7: '==' + self.match("==") + + + + + + + finally: + + pass + + # $ANTLR end T94 + + + + # $ANTLR start T95 + def mT95(self, ): + + try: + self.type = T95 + + # C.g:77:5: ( '!=' ) + # C.g:77:7: '!=' + self.match("!=") + + + + + + + finally: + + pass + + # $ANTLR end T95 + + + + # $ANTLR start T96 + def mT96(self, ): + + try: + self.type = T96 + + # C.g:78:5: ( '<' ) + # C.g:78:7: '<' + self.match(u'<') + + + + + + finally: + + pass + + # $ANTLR end T96 + + + + # $ANTLR start T97 + def mT97(self, ): + + try: + self.type = T97 + + # C.g:79:5: ( '>' ) + # C.g:79:7: '>' + self.match(u'>') + + + + + + finally: + + pass + + # $ANTLR end T97 + + + + # $ANTLR start T98 + def mT98(self, ): + + try: + self.type = T98 + + # C.g:80:5: ( '<=' ) + # C.g:80:7: '<=' + self.match("<=") + + + + + + + finally: + + pass + + # $ANTLR end T98 + + + + # $ANTLR start T99 + def mT99(self, ): + + try: + self.type = T99 + + # C.g:81:5: ( '>=' ) + # C.g:81:7: '>=' + self.match(">=") + + + + + + + finally: + + pass + + # $ANTLR end T99 + + + + # $ANTLR start T100 + def mT100(self, ): + + try: + self.type = T100 + + # C.g:82:6: ( '<<' ) + # C.g:82:8: '<<' + self.match("<<") + + + + + + + finally: + + pass + + # $ANTLR end T100 + + + + # $ANTLR start T101 + def mT101(self, ): + + try: + self.type = T101 + + # C.g:83:6: ( '>>' ) + # C.g:83:8: '>>' + self.match(">>") + + + + + + + finally: + + pass + + # $ANTLR end T101 + + + + # $ANTLR start T102 + def mT102(self, ): + + try: + self.type = T102 + + # C.g:84:6: ( '__asm__' ) + # C.g:84:8: '__asm__' + self.match("__asm__") + + + + + + + finally: + + pass + + # $ANTLR end T102 + + + + # $ANTLR start T103 + def mT103(self, ): + + try: + self.type = T103 + + # C.g:85:6: ( '_asm' ) + # C.g:85:8: '_asm' + self.match("_asm") + + + + + + + finally: + + pass + + # $ANTLR end T103 + + + + # $ANTLR start T104 + def mT104(self, ): + + try: + self.type = T104 + + # C.g:86:6: ( '__asm' ) + # C.g:86:8: '__asm' + self.match("__asm") + + + + + + + finally: + + pass + + # $ANTLR end T104 + + + + # $ANTLR start T105 + def mT105(self, ): + + try: + self.type = T105 + + # C.g:87:6: ( 'case' ) + # C.g:87:8: 'case' + self.match("case") + + + + + + + finally: + + pass + + # $ANTLR end T105 + + + + # $ANTLR start T106 + def mT106(self, ): + + try: + self.type = T106 + + # C.g:88:6: ( 'default' ) + # C.g:88:8: 'default' + self.match("default") + + + + + + + finally: + + pass + + # $ANTLR end T106 + + + + # $ANTLR start T107 + def mT107(self, ): + + try: + self.type = T107 + + # C.g:89:6: ( 'if' ) + # C.g:89:8: 'if' + self.match("if") + + + + + + + finally: + + pass + + # $ANTLR end T107 + + + + # $ANTLR start T108 + def mT108(self, ): + + try: + self.type = T108 + + # C.g:90:6: ( 'else' ) + # C.g:90:8: 'else' + self.match("else") + + + + + + + finally: + + pass + + # $ANTLR end T108 + + + + # $ANTLR start T109 + def mT109(self, ): + + try: + self.type = T109 + + # C.g:91:6: ( 'switch' ) + # C.g:91:8: 'switch' + self.match("switch") + + + + + + + finally: + + pass + + # $ANTLR end T109 + + + + # $ANTLR start T110 + def mT110(self, ): + + try: + self.type = T110 + + # C.g:92:6: ( 'while' ) + # C.g:92:8: 'while' + self.match("while") + + + + + + + finally: + + pass + + # $ANTLR end T110 + + + + # $ANTLR start T111 + def mT111(self, ): + + try: + self.type = T111 + + # C.g:93:6: ( 'do' ) + # C.g:93:8: 'do' + self.match("do") + + + + + + + finally: + + pass + + # $ANTLR end T111 + + + + # $ANTLR start T112 + def mT112(self, ): + + try: + self.type = T112 + + # C.g:94:6: ( 'for' ) + # C.g:94:8: 'for' + self.match("for") + + + + + + + finally: + + pass + + # $ANTLR end T112 + + + + # $ANTLR start T113 + def mT113(self, ): + + try: + self.type = T113 + + # C.g:95:6: ( 'goto' ) + # C.g:95:8: 'goto' + self.match("goto") + + + + + + + finally: + + pass + + # $ANTLR end T113 + + + + # $ANTLR start T114 + def mT114(self, ): + + try: + self.type = T114 + + # C.g:96:6: ( 'continue' ) + # C.g:96:8: 'continue' + self.match("continue") + + + + + + + finally: + + pass + + # $ANTLR end T114 + + + + # $ANTLR start T115 + def mT115(self, ): + + try: + self.type = T115 + + # C.g:97:6: ( 'break' ) + # C.g:97:8: 'break' + self.match("break") + + + + + + + finally: + + pass + + # $ANTLR end T115 + + + + # $ANTLR start T116 + def mT116(self, ): + + try: + self.type = T116 + + # C.g:98:6: ( 'return' ) + # C.g:98:8: 'return' + self.match("return") + + + + + + + finally: + + pass + + # $ANTLR end T116 + + + + # $ANTLR start IDENTIFIER + def mIDENTIFIER(self, ): + + try: + self.type = IDENTIFIER + + # C.g:533:2: ( LETTER ( LETTER | '0' .. '9' )* ) + # C.g:533:4: LETTER ( LETTER | '0' .. '9' )* + self.mLETTER() + + # C.g:533:11: ( LETTER | '0' .. '9' )* + while True: #loop1 + alt1 = 2 + LA1_0 = self.input.LA(1) + + if (LA1_0 == u'$' or (u'0' <= LA1_0 <= u'9') or (u'A' <= LA1_0 <= u'Z') or LA1_0 == u'_' or (u'a' <= LA1_0 <= u'z')) : + alt1 = 1 + + + if alt1 == 1: + # C.g: + if self.input.LA(1) == u'$' or (u'0' <= self.input.LA(1) <= u'9') or (u'A' <= self.input.LA(1) <= u'Z') or self.input.LA(1) == u'_' or (u'a' <= self.input.LA(1) <= u'z'): + self.input.consume(); + + else: + mse = MismatchedSetException(None, self.input) + self.recover(mse) + raise mse + + + + + else: + break #loop1 + + + + + + + finally: + + pass + + # $ANTLR end IDENTIFIER + + + + # $ANTLR start LETTER + def mLETTER(self, ): + + try: + # C.g:538:2: ( '$' | 'A' .. 'Z' | 'a' .. 'z' | '_' ) + # C.g: + if self.input.LA(1) == u'$' or (u'A' <= self.input.LA(1) <= u'Z') or self.input.LA(1) == u'_' or (u'a' <= self.input.LA(1) <= u'z'): + self.input.consume(); + + else: + mse = MismatchedSetException(None, self.input) + self.recover(mse) + raise mse + + + + + + + finally: + + pass + + # $ANTLR end LETTER + + + + # $ANTLR start CHARACTER_LITERAL + def mCHARACTER_LITERAL(self, ): + + try: + self.type = CHARACTER_LITERAL + + # C.g:545:5: ( ( 'L' )? '\\'' ( EscapeSequence | ~ ( '\\'' | '\\\\' ) ) '\\'' ) + # C.g:545:9: ( 'L' )? '\\'' ( EscapeSequence | ~ ( '\\'' | '\\\\' ) ) '\\'' + # C.g:545:9: ( 'L' )? + alt2 = 2 + LA2_0 = self.input.LA(1) + + if (LA2_0 == u'L') : + alt2 = 1 + if alt2 == 1: + # C.g:545:10: 'L' + self.match(u'L') + + + + + self.match(u'\'') + + # C.g:545:21: ( EscapeSequence | ~ ( '\\'' | '\\\\' ) ) + alt3 = 2 + LA3_0 = self.input.LA(1) + + if (LA3_0 == u'\\') : + alt3 = 1 + elif ((u'\u0000' <= LA3_0 <= u'&') or (u'(' <= LA3_0 <= u'[') or (u']' <= LA3_0 <= u'\uFFFE')) : + alt3 = 2 + else: + nvae = NoViableAltException("545:21: ( EscapeSequence | ~ ( '\\'' | '\\\\' ) )", 3, 0, self.input) + + raise nvae + + if alt3 == 1: + # C.g:545:23: EscapeSequence + self.mEscapeSequence() + + + + elif alt3 == 2: + # C.g:545:40: ~ ( '\\'' | '\\\\' ) + if (u'\u0000' <= self.input.LA(1) <= u'&') or (u'(' <= self.input.LA(1) <= u'[') or (u']' <= self.input.LA(1) <= u'\uFFFE'): + self.input.consume(); + + else: + mse = MismatchedSetException(None, self.input) + self.recover(mse) + raise mse + + + + + + self.match(u'\'') + + + + + + finally: + + pass + + # $ANTLR end CHARACTER_LITERAL + + + + # $ANTLR start STRING_LITERAL + def mSTRING_LITERAL(self, ): + + try: + self.type = STRING_LITERAL + + # C.g:549:5: ( ( 'L' )? '\"' ( EscapeSequence | ~ ( '\\\\' | '\"' ) )* '\"' ) + # C.g:549:8: ( 'L' )? '\"' ( EscapeSequence | ~ ( '\\\\' | '\"' ) )* '\"' + # C.g:549:8: ( 'L' )? + alt4 = 2 + LA4_0 = self.input.LA(1) + + if (LA4_0 == u'L') : + alt4 = 1 + if alt4 == 1: + # C.g:549:9: 'L' + self.match(u'L') + + + + + self.match(u'"') + + # C.g:549:19: ( EscapeSequence | ~ ( '\\\\' | '\"' ) )* + while True: #loop5 + alt5 = 3 + LA5_0 = self.input.LA(1) + + if (LA5_0 == u'\\') : + alt5 = 1 + elif ((u'\u0000' <= LA5_0 <= u'!') or (u'#' <= LA5_0 <= u'[') or (u']' <= LA5_0 <= u'\uFFFE')) : + alt5 = 2 + + + if alt5 == 1: + # C.g:549:21: EscapeSequence + self.mEscapeSequence() + + + + elif alt5 == 2: + # C.g:549:38: ~ ( '\\\\' | '\"' ) + if (u'\u0000' <= self.input.LA(1) <= u'!') or (u'#' <= self.input.LA(1) <= u'[') or (u']' <= self.input.LA(1) <= u'\uFFFE'): + self.input.consume(); + + else: + mse = MismatchedSetException(None, self.input) + self.recover(mse) + raise mse + + + + + else: + break #loop5 + + + self.match(u'"') + + + + + + finally: + + pass + + # $ANTLR end STRING_LITERAL + + + + # $ANTLR start HEX_LITERAL + def mHEX_LITERAL(self, ): + + try: + self.type = HEX_LITERAL + + # C.g:552:13: ( '0' ( 'x' | 'X' ) ( HexDigit )+ ( IntegerTypeSuffix )? ) + # C.g:552:15: '0' ( 'x' | 'X' ) ( HexDigit )+ ( IntegerTypeSuffix )? + self.match(u'0') + + if self.input.LA(1) == u'X' or self.input.LA(1) == u'x': + self.input.consume(); + + else: + mse = MismatchedSetException(None, self.input) + self.recover(mse) + raise mse + + + # C.g:552:29: ( HexDigit )+ + cnt6 = 0 + while True: #loop6 + alt6 = 2 + LA6_0 = self.input.LA(1) + + if ((u'0' <= LA6_0 <= u'9') or (u'A' <= LA6_0 <= u'F') or (u'a' <= LA6_0 <= u'f')) : + alt6 = 1 + + + if alt6 == 1: + # C.g:552:29: HexDigit + self.mHexDigit() + + + + else: + if cnt6 >= 1: + break #loop6 + + eee = EarlyExitException(6, self.input) + raise eee + + cnt6 += 1 + + + # C.g:552:39: ( IntegerTypeSuffix )? + alt7 = 2 + LA7_0 = self.input.LA(1) + + if (LA7_0 == u'L' or LA7_0 == u'U' or LA7_0 == u'l' or LA7_0 == u'u') : + alt7 = 1 + if alt7 == 1: + # C.g:552:39: IntegerTypeSuffix + self.mIntegerTypeSuffix() + + + + + + + + + finally: + + pass + + # $ANTLR end HEX_LITERAL + + + + # $ANTLR start DECIMAL_LITERAL + def mDECIMAL_LITERAL(self, ): + + try: + self.type = DECIMAL_LITERAL + + # C.g:554:17: ( ( '0' | '1' .. '9' ( '0' .. '9' )* ) ( IntegerTypeSuffix )? ) + # C.g:554:19: ( '0' | '1' .. '9' ( '0' .. '9' )* ) ( IntegerTypeSuffix )? + # C.g:554:19: ( '0' | '1' .. '9' ( '0' .. '9' )* ) + alt9 = 2 + LA9_0 = self.input.LA(1) + + if (LA9_0 == u'0') : + alt9 = 1 + elif ((u'1' <= LA9_0 <= u'9')) : + alt9 = 2 + else: + nvae = NoViableAltException("554:19: ( '0' | '1' .. '9' ( '0' .. '9' )* )", 9, 0, self.input) + + raise nvae + + if alt9 == 1: + # C.g:554:20: '0' + self.match(u'0') + + + + elif alt9 == 2: + # C.g:554:26: '1' .. '9' ( '0' .. '9' )* + self.matchRange(u'1', u'9') + + # C.g:554:35: ( '0' .. '9' )* + while True: #loop8 + alt8 = 2 + LA8_0 = self.input.LA(1) + + if ((u'0' <= LA8_0 <= u'9')) : + alt8 = 1 + + + if alt8 == 1: + # C.g:554:35: '0' .. '9' + self.matchRange(u'0', u'9') + + + + else: + break #loop8 + + + + + + # C.g:554:46: ( IntegerTypeSuffix )? + alt10 = 2 + LA10_0 = self.input.LA(1) + + if (LA10_0 == u'L' or LA10_0 == u'U' or LA10_0 == u'l' or LA10_0 == u'u') : + alt10 = 1 + if alt10 == 1: + # C.g:554:46: IntegerTypeSuffix + self.mIntegerTypeSuffix() + + + + + + + + + finally: + + pass + + # $ANTLR end DECIMAL_LITERAL + + + + # $ANTLR start OCTAL_LITERAL + def mOCTAL_LITERAL(self, ): + + try: + self.type = OCTAL_LITERAL + + # C.g:556:15: ( '0' ( '0' .. '7' )+ ( IntegerTypeSuffix )? ) + # C.g:556:17: '0' ( '0' .. '7' )+ ( IntegerTypeSuffix )? + self.match(u'0') + + # C.g:556:21: ( '0' .. '7' )+ + cnt11 = 0 + while True: #loop11 + alt11 = 2 + LA11_0 = self.input.LA(1) + + if ((u'0' <= LA11_0 <= u'7')) : + alt11 = 1 + + + if alt11 == 1: + # C.g:556:22: '0' .. '7' + self.matchRange(u'0', u'7') + + + + else: + if cnt11 >= 1: + break #loop11 + + eee = EarlyExitException(11, self.input) + raise eee + + cnt11 += 1 + + + # C.g:556:33: ( IntegerTypeSuffix )? + alt12 = 2 + LA12_0 = self.input.LA(1) + + if (LA12_0 == u'L' or LA12_0 == u'U' or LA12_0 == u'l' or LA12_0 == u'u') : + alt12 = 1 + if alt12 == 1: + # C.g:556:33: IntegerTypeSuffix + self.mIntegerTypeSuffix() + + + + + + + + + finally: + + pass + + # $ANTLR end OCTAL_LITERAL + + + + # $ANTLR start HexDigit + def mHexDigit(self, ): + + try: + # C.g:559:10: ( ( '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' ) ) + # C.g:559:12: ( '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' ) + if (u'0' <= self.input.LA(1) <= u'9') or (u'A' <= self.input.LA(1) <= u'F') or (u'a' <= self.input.LA(1) <= u'f'): + self.input.consume(); + + else: + mse = MismatchedSetException(None, self.input) + self.recover(mse) + raise mse + + + + + + + finally: + + pass + + # $ANTLR end HexDigit + + + + # $ANTLR start IntegerTypeSuffix + def mIntegerTypeSuffix(self, ): + + try: + # C.g:563:2: ( ( 'u' | 'U' ) | ( 'l' | 'L' ) | ( 'u' | 'U' ) ( 'l' | 'L' ) | ( 'u' | 'U' ) ( 'l' | 'L' ) ( 'l' | 'L' ) ) + alt13 = 4 + LA13_0 = self.input.LA(1) + + if (LA13_0 == u'U' or LA13_0 == u'u') : + LA13_1 = self.input.LA(2) + + if (LA13_1 == u'L' or LA13_1 == u'l') : + LA13_3 = self.input.LA(3) + + if (LA13_3 == u'L' or LA13_3 == u'l') : + alt13 = 4 + else: + alt13 = 3 + else: + alt13 = 1 + elif (LA13_0 == u'L' or LA13_0 == u'l') : + alt13 = 2 + else: + nvae = NoViableAltException("561:1: fragment IntegerTypeSuffix : ( ( 'u' | 'U' ) | ( 'l' | 'L' ) | ( 'u' | 'U' ) ( 'l' | 'L' ) | ( 'u' | 'U' ) ( 'l' | 'L' ) ( 'l' | 'L' ) );", 13, 0, self.input) + + raise nvae + + if alt13 == 1: + # C.g:563:4: ( 'u' | 'U' ) + if self.input.LA(1) == u'U' or self.input.LA(1) == u'u': + self.input.consume(); + + else: + mse = MismatchedSetException(None, self.input) + self.recover(mse) + raise mse + + + + + elif alt13 == 2: + # C.g:564:4: ( 'l' | 'L' ) + if self.input.LA(1) == u'L' or self.input.LA(1) == u'l': + self.input.consume(); + + else: + mse = MismatchedSetException(None, self.input) + self.recover(mse) + raise mse + + + + + elif alt13 == 3: + # C.g:565:4: ( 'u' | 'U' ) ( 'l' | 'L' ) + if self.input.LA(1) == u'U' or self.input.LA(1) == u'u': + self.input.consume(); + + else: + mse = MismatchedSetException(None, self.input) + self.recover(mse) + raise mse + + + if self.input.LA(1) == u'L' or self.input.LA(1) == u'l': + self.input.consume(); + + else: + mse = MismatchedSetException(None, self.input) + self.recover(mse) + raise mse + + + + + elif alt13 == 4: + # C.g:566:4: ( 'u' | 'U' ) ( 'l' | 'L' ) ( 'l' | 'L' ) + if self.input.LA(1) == u'U' or self.input.LA(1) == u'u': + self.input.consume(); + + else: + mse = MismatchedSetException(None, self.input) + self.recover(mse) + raise mse + + + if self.input.LA(1) == u'L' or self.input.LA(1) == u'l': + self.input.consume(); + + else: + mse = MismatchedSetException(None, self.input) + self.recover(mse) + raise mse + + + if self.input.LA(1) == u'L' or self.input.LA(1) == u'l': + self.input.consume(); + + else: + mse = MismatchedSetException(None, self.input) + self.recover(mse) + raise mse + + + + + + finally: + + pass + + # $ANTLR end IntegerTypeSuffix + + + + # $ANTLR start FLOATING_POINT_LITERAL + def mFLOATING_POINT_LITERAL(self, ): + + try: + self.type = FLOATING_POINT_LITERAL + + # C.g:570:5: ( ( '0' .. '9' )+ '.' ( '0' .. '9' )* ( Exponent )? ( FloatTypeSuffix )? | '.' ( '0' .. '9' )+ ( Exponent )? ( FloatTypeSuffix )? | ( '0' .. '9' )+ Exponent ( FloatTypeSuffix )? | ( '0' .. '9' )+ ( Exponent )? FloatTypeSuffix ) + alt25 = 4 + alt25 = self.dfa25.predict(self.input) + if alt25 == 1: + # C.g:570:9: ( '0' .. '9' )+ '.' ( '0' .. '9' )* ( Exponent )? ( FloatTypeSuffix )? + # C.g:570:9: ( '0' .. '9' )+ + cnt14 = 0 + while True: #loop14 + alt14 = 2 + LA14_0 = self.input.LA(1) + + if ((u'0' <= LA14_0 <= u'9')) : + alt14 = 1 + + + if alt14 == 1: + # C.g:570:10: '0' .. '9' + self.matchRange(u'0', u'9') + + + + else: + if cnt14 >= 1: + break #loop14 + + eee = EarlyExitException(14, self.input) + raise eee + + cnt14 += 1 + + + self.match(u'.') + + # C.g:570:25: ( '0' .. '9' )* + while True: #loop15 + alt15 = 2 + LA15_0 = self.input.LA(1) + + if ((u'0' <= LA15_0 <= u'9')) : + alt15 = 1 + + + if alt15 == 1: + # C.g:570:26: '0' .. '9' + self.matchRange(u'0', u'9') + + + + else: + break #loop15 + + + # C.g:570:37: ( Exponent )? + alt16 = 2 + LA16_0 = self.input.LA(1) + + if (LA16_0 == u'E' or LA16_0 == u'e') : + alt16 = 1 + if alt16 == 1: + # C.g:570:37: Exponent + self.mExponent() + + + + + # C.g:570:47: ( FloatTypeSuffix )? + alt17 = 2 + LA17_0 = self.input.LA(1) + + if (LA17_0 == u'D' or LA17_0 == u'F' or LA17_0 == u'd' or LA17_0 == u'f') : + alt17 = 1 + if alt17 == 1: + # C.g:570:47: FloatTypeSuffix + self.mFloatTypeSuffix() + + + + + + + elif alt25 == 2: + # C.g:571:9: '.' ( '0' .. '9' )+ ( Exponent )? ( FloatTypeSuffix )? + self.match(u'.') + + # C.g:571:13: ( '0' .. '9' )+ + cnt18 = 0 + while True: #loop18 + alt18 = 2 + LA18_0 = self.input.LA(1) + + if ((u'0' <= LA18_0 <= u'9')) : + alt18 = 1 + + + if alt18 == 1: + # C.g:571:14: '0' .. '9' + self.matchRange(u'0', u'9') + + + + else: + if cnt18 >= 1: + break #loop18 + + eee = EarlyExitException(18, self.input) + raise eee + + cnt18 += 1 + + + # C.g:571:25: ( Exponent )? + alt19 = 2 + LA19_0 = self.input.LA(1) + + if (LA19_0 == u'E' or LA19_0 == u'e') : + alt19 = 1 + if alt19 == 1: + # C.g:571:25: Exponent + self.mExponent() + + + + + # C.g:571:35: ( FloatTypeSuffix )? + alt20 = 2 + LA20_0 = self.input.LA(1) + + if (LA20_0 == u'D' or LA20_0 == u'F' or LA20_0 == u'd' or LA20_0 == u'f') : + alt20 = 1 + if alt20 == 1: + # C.g:571:35: FloatTypeSuffix + self.mFloatTypeSuffix() + + + + + + + elif alt25 == 3: + # C.g:572:9: ( '0' .. '9' )+ Exponent ( FloatTypeSuffix )? + # C.g:572:9: ( '0' .. '9' )+ + cnt21 = 0 + while True: #loop21 + alt21 = 2 + LA21_0 = self.input.LA(1) + + if ((u'0' <= LA21_0 <= u'9')) : + alt21 = 1 + + + if alt21 == 1: + # C.g:572:10: '0' .. '9' + self.matchRange(u'0', u'9') + + + + else: + if cnt21 >= 1: + break #loop21 + + eee = EarlyExitException(21, self.input) + raise eee + + cnt21 += 1 + + + self.mExponent() + + # C.g:572:30: ( FloatTypeSuffix )? + alt22 = 2 + LA22_0 = self.input.LA(1) + + if (LA22_0 == u'D' or LA22_0 == u'F' or LA22_0 == u'd' or LA22_0 == u'f') : + alt22 = 1 + if alt22 == 1: + # C.g:572:30: FloatTypeSuffix + self.mFloatTypeSuffix() + + + + + + + elif alt25 == 4: + # C.g:573:9: ( '0' .. '9' )+ ( Exponent )? FloatTypeSuffix + # C.g:573:9: ( '0' .. '9' )+ + cnt23 = 0 + while True: #loop23 + alt23 = 2 + LA23_0 = self.input.LA(1) + + if ((u'0' <= LA23_0 <= u'9')) : + alt23 = 1 + + + if alt23 == 1: + # C.g:573:10: '0' .. '9' + self.matchRange(u'0', u'9') + + + + else: + if cnt23 >= 1: + break #loop23 + + eee = EarlyExitException(23, self.input) + raise eee + + cnt23 += 1 + + + # C.g:573:21: ( Exponent )? + alt24 = 2 + LA24_0 = self.input.LA(1) + + if (LA24_0 == u'E' or LA24_0 == u'e') : + alt24 = 1 + if alt24 == 1: + # C.g:573:21: Exponent + self.mExponent() + + + + + self.mFloatTypeSuffix() + + + + + finally: + + pass + + # $ANTLR end FLOATING_POINT_LITERAL + + + + # $ANTLR start Exponent + def mExponent(self, ): + + try: + # C.g:577:10: ( ( 'e' | 'E' ) ( '+' | '-' )? ( '0' .. '9' )+ ) + # C.g:577:12: ( 'e' | 'E' ) ( '+' | '-' )? ( '0' .. '9' )+ + if self.input.LA(1) == u'E' or self.input.LA(1) == u'e': + self.input.consume(); + + else: + mse = MismatchedSetException(None, self.input) + self.recover(mse) + raise mse + + + # C.g:577:22: ( '+' | '-' )? + alt26 = 2 + LA26_0 = self.input.LA(1) + + if (LA26_0 == u'+' or LA26_0 == u'-') : + alt26 = 1 + if alt26 == 1: + # C.g: + if self.input.LA(1) == u'+' or self.input.LA(1) == u'-': + self.input.consume(); + + else: + mse = MismatchedSetException(None, self.input) + self.recover(mse) + raise mse + + + + + + # C.g:577:33: ( '0' .. '9' )+ + cnt27 = 0 + while True: #loop27 + alt27 = 2 + LA27_0 = self.input.LA(1) + + if ((u'0' <= LA27_0 <= u'9')) : + alt27 = 1 + + + if alt27 == 1: + # C.g:577:34: '0' .. '9' + self.matchRange(u'0', u'9') + + + + else: + if cnt27 >= 1: + break #loop27 + + eee = EarlyExitException(27, self.input) + raise eee + + cnt27 += 1 + + + + + + + finally: + + pass + + # $ANTLR end Exponent + + + + # $ANTLR start FloatTypeSuffix + def mFloatTypeSuffix(self, ): + + try: + # C.g:580:17: ( ( 'f' | 'F' | 'd' | 'D' ) ) + # C.g:580:19: ( 'f' | 'F' | 'd' | 'D' ) + if self.input.LA(1) == u'D' or self.input.LA(1) == u'F' or self.input.LA(1) == u'd' or self.input.LA(1) == u'f': + self.input.consume(); + + else: + mse = MismatchedSetException(None, self.input) + self.recover(mse) + raise mse + + + + + + + finally: + + pass + + # $ANTLR end FloatTypeSuffix + + + + # $ANTLR start EscapeSequence + def mEscapeSequence(self, ): + + try: + # C.g:584:5: ( '\\\\' ( 'b' | 't' | 'n' | 'f' | 'r' | '\\\"' | '\\'' | '\\\\' ) | OctalEscape ) + alt28 = 2 + LA28_0 = self.input.LA(1) + + if (LA28_0 == u'\\') : + LA28_1 = self.input.LA(2) + + if (LA28_1 == u'"' or LA28_1 == u'\'' or LA28_1 == u'\\' or LA28_1 == u'b' or LA28_1 == u'f' or LA28_1 == u'n' or LA28_1 == u'r' or LA28_1 == u't') : + alt28 = 1 + elif ((u'0' <= LA28_1 <= u'7')) : + alt28 = 2 + else: + nvae = NoViableAltException("582:1: fragment EscapeSequence : ( '\\\\' ( 'b' | 't' | 'n' | 'f' | 'r' | '\\\"' | '\\'' | '\\\\' ) | OctalEscape );", 28, 1, self.input) + + raise nvae + + else: + nvae = NoViableAltException("582:1: fragment EscapeSequence : ( '\\\\' ( 'b' | 't' | 'n' | 'f' | 'r' | '\\\"' | '\\'' | '\\\\' ) | OctalEscape );", 28, 0, self.input) + + raise nvae + + if alt28 == 1: + # C.g:584:8: '\\\\' ( 'b' | 't' | 'n' | 'f' | 'r' | '\\\"' | '\\'' | '\\\\' ) + self.match(u'\\') + + if self.input.LA(1) == u'"' or self.input.LA(1) == u'\'' or self.input.LA(1) == u'\\' or self.input.LA(1) == u'b' or self.input.LA(1) == u'f' or self.input.LA(1) == u'n' or self.input.LA(1) == u'r' or self.input.LA(1) == u't': + self.input.consume(); + + else: + mse = MismatchedSetException(None, self.input) + self.recover(mse) + raise mse + + + + + elif alt28 == 2: + # C.g:585:9: OctalEscape + self.mOctalEscape() + + + + + finally: + + pass + + # $ANTLR end EscapeSequence + + + + # $ANTLR start OctalEscape + def mOctalEscape(self, ): + + try: + # C.g:590:5: ( '\\\\' ( '0' .. '3' ) ( '0' .. '7' ) ( '0' .. '7' ) | '\\\\' ( '0' .. '7' ) ( '0' .. '7' ) | '\\\\' ( '0' .. '7' ) ) + alt29 = 3 + LA29_0 = self.input.LA(1) + + if (LA29_0 == u'\\') : + LA29_1 = self.input.LA(2) + + if ((u'0' <= LA29_1 <= u'3')) : + LA29_2 = self.input.LA(3) + + if ((u'0' <= LA29_2 <= u'7')) : + LA29_4 = self.input.LA(4) + + if ((u'0' <= LA29_4 <= u'7')) : + alt29 = 1 + else: + alt29 = 2 + else: + alt29 = 3 + elif ((u'4' <= LA29_1 <= u'7')) : + LA29_3 = self.input.LA(3) + + if ((u'0' <= LA29_3 <= u'7')) : + alt29 = 2 + else: + alt29 = 3 + else: + nvae = NoViableAltException("588:1: fragment OctalEscape : ( '\\\\' ( '0' .. '3' ) ( '0' .. '7' ) ( '0' .. '7' ) | '\\\\' ( '0' .. '7' ) ( '0' .. '7' ) | '\\\\' ( '0' .. '7' ) );", 29, 1, self.input) + + raise nvae + + else: + nvae = NoViableAltException("588:1: fragment OctalEscape : ( '\\\\' ( '0' .. '3' ) ( '0' .. '7' ) ( '0' .. '7' ) | '\\\\' ( '0' .. '7' ) ( '0' .. '7' ) | '\\\\' ( '0' .. '7' ) );", 29, 0, self.input) + + raise nvae + + if alt29 == 1: + # C.g:590:9: '\\\\' ( '0' .. '3' ) ( '0' .. '7' ) ( '0' .. '7' ) + self.match(u'\\') + + # C.g:590:14: ( '0' .. '3' ) + # C.g:590:15: '0' .. '3' + self.matchRange(u'0', u'3') + + + + + # C.g:590:25: ( '0' .. '7' ) + # C.g:590:26: '0' .. '7' + self.matchRange(u'0', u'7') + + + + + # C.g:590:36: ( '0' .. '7' ) + # C.g:590:37: '0' .. '7' + self.matchRange(u'0', u'7') + + + + + + + elif alt29 == 2: + # C.g:591:9: '\\\\' ( '0' .. '7' ) ( '0' .. '7' ) + self.match(u'\\') + + # C.g:591:14: ( '0' .. '7' ) + # C.g:591:15: '0' .. '7' + self.matchRange(u'0', u'7') + + + + + # C.g:591:25: ( '0' .. '7' ) + # C.g:591:26: '0' .. '7' + self.matchRange(u'0', u'7') + + + + + + + elif alt29 == 3: + # C.g:592:9: '\\\\' ( '0' .. '7' ) + self.match(u'\\') + + # C.g:592:14: ( '0' .. '7' ) + # C.g:592:15: '0' .. '7' + self.matchRange(u'0', u'7') + + + + + + + + finally: + + pass + + # $ANTLR end OctalEscape + + + + # $ANTLR start UnicodeEscape + def mUnicodeEscape(self, ): + + try: + # C.g:597:5: ( '\\\\' 'u' HexDigit HexDigit HexDigit HexDigit ) + # C.g:597:9: '\\\\' 'u' HexDigit HexDigit HexDigit HexDigit + self.match(u'\\') + + self.match(u'u') + + self.mHexDigit() + + self.mHexDigit() + + self.mHexDigit() + + self.mHexDigit() + + + + + + finally: + + pass + + # $ANTLR end UnicodeEscape + + + + # $ANTLR start WS + def mWS(self, ): + + try: + self.type = WS + + # C.g:600:5: ( ( ' ' | '\\r' | '\\t' | '\\u000C' | '\\n' ) ) + # C.g:600:8: ( ' ' | '\\r' | '\\t' | '\\u000C' | '\\n' ) + if (u'\t' <= self.input.LA(1) <= u'\n') or (u'\f' <= self.input.LA(1) <= u'\r') or self.input.LA(1) == u' ': + self.input.consume(); + + else: + mse = MismatchedSetException(None, self.input) + self.recover(mse) + raise mse + + + #action start + self.channel=HIDDEN; + #action end + + + + + finally: + + pass + + # $ANTLR end WS + + + + # $ANTLR start BS + def mBS(self, ): + + try: + self.type = BS + + # C.g:604:5: ( ( '\\\\' ) ) + # C.g:604:7: ( '\\\\' ) + # C.g:604:7: ( '\\\\' ) + # C.g:604:8: '\\\\' + self.match(u'\\') + + + + + #action start + self.channel=HIDDEN; + #action end + + + + + finally: + + pass + + # $ANTLR end BS + + + + # $ANTLR start UnicodeVocabulary + def mUnicodeVocabulary(self, ): + + try: + self.type = UnicodeVocabulary + + # C.g:612:5: ( '\\u0003' .. '\\uFFFE' ) + # C.g:612:7: '\\u0003' .. '\\uFFFE' + self.matchRange(u'\u0003', u'\uFFFE') + + + + + + finally: + + pass + + # $ANTLR end UnicodeVocabulary + + + + # $ANTLR start COMMENT + def mCOMMENT(self, ): + + try: + self.type = COMMENT + + # C.g:615:5: ( '/*' ( options {greedy=false; } : . )* '*/' ) + # C.g:615:9: '/*' ( options {greedy=false; } : . )* '*/' + self.match("/*") + + + # C.g:615:14: ( options {greedy=false; } : . )* + while True: #loop30 + alt30 = 2 + LA30_0 = self.input.LA(1) + + if (LA30_0 == u'*') : + LA30_1 = self.input.LA(2) + + if (LA30_1 == u'/') : + alt30 = 2 + elif ((u'\u0000' <= LA30_1 <= u'.') or (u'0' <= LA30_1 <= u'\uFFFE')) : + alt30 = 1 + + + elif ((u'\u0000' <= LA30_0 <= u')') or (u'+' <= LA30_0 <= u'\uFFFE')) : + alt30 = 1 + + + if alt30 == 1: + # C.g:615:42: . + self.matchAny() + + + + else: + break #loop30 + + + self.match("*/") + + + #action start + self.channel=HIDDEN; + #action end + + + + + finally: + + pass + + # $ANTLR end COMMENT + + + + # $ANTLR start LINE_COMMENT + def mLINE_COMMENT(self, ): + + try: + self.type = LINE_COMMENT + + # C.g:620:5: ( '//' (~ ( '\\n' | '\\r' ) )* ( '\\r' )? '\\n' ) + # C.g:620:7: '//' (~ ( '\\n' | '\\r' ) )* ( '\\r' )? '\\n' + self.match("//") + + + # C.g:620:12: (~ ( '\\n' | '\\r' ) )* + while True: #loop31 + alt31 = 2 + LA31_0 = self.input.LA(1) + + if ((u'\u0000' <= LA31_0 <= u'\t') or (u'\u000B' <= LA31_0 <= u'\f') or (u'\u000E' <= LA31_0 <= u'\uFFFE')) : + alt31 = 1 + + + if alt31 == 1: + # C.g:620:12: ~ ( '\\n' | '\\r' ) + if (u'\u0000' <= self.input.LA(1) <= u'\t') or (u'\u000B' <= self.input.LA(1) <= u'\f') or (u'\u000E' <= self.input.LA(1) <= u'\uFFFE'): + self.input.consume(); + + else: + mse = MismatchedSetException(None, self.input) + self.recover(mse) + raise mse + + + + + else: + break #loop31 + + + # C.g:620:26: ( '\\r' )? + alt32 = 2 + LA32_0 = self.input.LA(1) + + if (LA32_0 == u'\r') : + alt32 = 1 + if alt32 == 1: + # C.g:620:26: '\\r' + self.match(u'\r') + + + + + self.match(u'\n') + + #action start + self.channel=HIDDEN; + #action end + + + + + finally: + + pass + + # $ANTLR end LINE_COMMENT + + + + # $ANTLR start LINE_COMMAND + def mLINE_COMMAND(self, ): + + try: + self.type = LINE_COMMAND + + # C.g:625:5: ( '#' (~ ( '\\n' | '\\r' ) )* ( '\\r' )? '\\n' ) + # C.g:625:7: '#' (~ ( '\\n' | '\\r' ) )* ( '\\r' )? '\\n' + self.match(u'#') + + # C.g:625:11: (~ ( '\\n' | '\\r' ) )* + while True: #loop33 + alt33 = 2 + LA33_0 = self.input.LA(1) + + if ((u'\u0000' <= LA33_0 <= u'\t') or (u'\u000B' <= LA33_0 <= u'\f') or (u'\u000E' <= LA33_0 <= u'\uFFFE')) : + alt33 = 1 + + + if alt33 == 1: + # C.g:625:11: ~ ( '\\n' | '\\r' ) + if (u'\u0000' <= self.input.LA(1) <= u'\t') or (u'\u000B' <= self.input.LA(1) <= u'\f') or (u'\u000E' <= self.input.LA(1) <= u'\uFFFE'): + self.input.consume(); + + else: + mse = MismatchedSetException(None, self.input) + self.recover(mse) + raise mse + + + + + else: + break #loop33 + + + # C.g:625:25: ( '\\r' )? + alt34 = 2 + LA34_0 = self.input.LA(1) + + if (LA34_0 == u'\r') : + alt34 = 1 + if alt34 == 1: + # C.g:625:25: '\\r' + self.match(u'\r') + + + + + self.match(u'\n') + + #action start + self.channel=HIDDEN; + #action end + + + + + finally: + + pass + + # $ANTLR end LINE_COMMAND + + + + def mTokens(self): + # C.g:1:8: ( T25 | T26 | T27 | T28 | T29 | T30 | T31 | T32 | T33 | T34 | T35 | T36 | T37 | T38 | T39 | T40 | T41 | T42 | T43 | T44 | T45 | T46 | T47 | T48 | T49 | T50 | T51 | T52 | T53 | T54 | T55 | T56 | T57 | T58 | T59 | T60 | T61 | T62 | T63 | T64 | T65 | T66 | T67 | T68 | T69 | T70 | T71 | T72 | T73 | T74 | T75 | T76 | T77 | T78 | T79 | T80 | T81 | T82 | T83 | T84 | T85 | T86 | T87 | T88 | T89 | T90 | T91 | T92 | T93 | T94 | T95 | T96 | T97 | T98 | T99 | T100 | T101 | T102 | T103 | T104 | T105 | T106 | T107 | T108 | T109 | T110 | T111 | T112 | T113 | T114 | T115 | T116 | IDENTIFIER | CHARACTER_LITERAL | STRING_LITERAL | HEX_LITERAL | DECIMAL_LITERAL | OCTAL_LITERAL | FLOATING_POINT_LITERAL | WS | BS | UnicodeVocabulary | COMMENT | LINE_COMMENT | LINE_COMMAND ) + alt35 = 105 + alt35 = self.dfa35.predict(self.input) + if alt35 == 1: + # C.g:1:10: T25 + self.mT25() + + + + elif alt35 == 2: + # C.g:1:14: T26 + self.mT26() + + + + elif alt35 == 3: + # C.g:1:18: T27 + self.mT27() + + + + elif alt35 == 4: + # C.g:1:22: T28 + self.mT28() + + + + elif alt35 == 5: + # C.g:1:26: T29 + self.mT29() + + + + elif alt35 == 6: + # C.g:1:30: T30 + self.mT30() + + + + elif alt35 == 7: + # C.g:1:34: T31 + self.mT31() + + + + elif alt35 == 8: + # C.g:1:38: T32 + self.mT32() + + + + elif alt35 == 9: + # C.g:1:42: T33 + self.mT33() + + + + elif alt35 == 10: + # C.g:1:46: T34 + self.mT34() + + + + elif alt35 == 11: + # C.g:1:50: T35 + self.mT35() + + + + elif alt35 == 12: + # C.g:1:54: T36 + self.mT36() + + + + elif alt35 == 13: + # C.g:1:58: T37 + self.mT37() + + + + elif alt35 == 14: + # C.g:1:62: T38 + self.mT38() + + + + elif alt35 == 15: + # C.g:1:66: T39 + self.mT39() + + + + elif alt35 == 16: + # C.g:1:70: T40 + self.mT40() + + + + elif alt35 == 17: + # C.g:1:74: T41 + self.mT41() + + + + elif alt35 == 18: + # C.g:1:78: T42 + self.mT42() + + + + elif alt35 == 19: + # C.g:1:82: T43 + self.mT43() + + + + elif alt35 == 20: + # C.g:1:86: T44 + self.mT44() + + + + elif alt35 == 21: + # C.g:1:90: T45 + self.mT45() + + + + elif alt35 == 22: + # C.g:1:94: T46 + self.mT46() + + + + elif alt35 == 23: + # C.g:1:98: T47 + self.mT47() + + + + elif alt35 == 24: + # C.g:1:102: T48 + self.mT48() + + + + elif alt35 == 25: + # C.g:1:106: T49 + self.mT49() + + + + elif alt35 == 26: + # C.g:1:110: T50 + self.mT50() + + + + elif alt35 == 27: + # C.g:1:114: T51 + self.mT51() + + + + elif alt35 == 28: + # C.g:1:118: T52 + self.mT52() + + + + elif alt35 == 29: + # C.g:1:122: T53 + self.mT53() + + + + elif alt35 == 30: + # C.g:1:126: T54 + self.mT54() + + + + elif alt35 == 31: + # C.g:1:130: T55 + self.mT55() + + + + elif alt35 == 32: + # C.g:1:134: T56 + self.mT56() + + + + elif alt35 == 33: + # C.g:1:138: T57 + self.mT57() + + + + elif alt35 == 34: + # C.g:1:142: T58 + self.mT58() + + + + elif alt35 == 35: + # C.g:1:146: T59 + self.mT59() + + + + elif alt35 == 36: + # C.g:1:150: T60 + self.mT60() + + + + elif alt35 == 37: + # C.g:1:154: T61 + self.mT61() + + + + elif alt35 == 38: + # C.g:1:158: T62 + self.mT62() + + + + elif alt35 == 39: + # C.g:1:162: T63 + self.mT63() + + + + elif alt35 == 40: + # C.g:1:166: T64 + self.mT64() + + + + elif alt35 == 41: + # C.g:1:170: T65 + self.mT65() + + + + elif alt35 == 42: + # C.g:1:174: T66 + self.mT66() + + + + elif alt35 == 43: + # C.g:1:178: T67 + self.mT67() + + + + elif alt35 == 44: + # C.g:1:182: T68 + self.mT68() + + + + elif alt35 == 45: + # C.g:1:186: T69 + self.mT69() + + + + elif alt35 == 46: + # C.g:1:190: T70 + self.mT70() + + + + elif alt35 == 47: + # C.g:1:194: T71 + self.mT71() + + + + elif alt35 == 48: + # C.g:1:198: T72 + self.mT72() + + + + elif alt35 == 49: + # C.g:1:202: T73 + self.mT73() + + + + elif alt35 == 50: + # C.g:1:206: T74 + self.mT74() + + + + elif alt35 == 51: + # C.g:1:210: T75 + self.mT75() + + + + elif alt35 == 52: + # C.g:1:214: T76 + self.mT76() + + + + elif alt35 == 53: + # C.g:1:218: T77 + self.mT77() + + + + elif alt35 == 54: + # C.g:1:222: T78 + self.mT78() + + + + elif alt35 == 55: + # C.g:1:226: T79 + self.mT79() + + + + elif alt35 == 56: + # C.g:1:230: T80 + self.mT80() + + + + elif alt35 == 57: + # C.g:1:234: T81 + self.mT81() + + + + elif alt35 == 58: + # C.g:1:238: T82 + self.mT82() + + + + elif alt35 == 59: + # C.g:1:242: T83 + self.mT83() + + + + elif alt35 == 60: + # C.g:1:246: T84 + self.mT84() + + + + elif alt35 == 61: + # C.g:1:250: T85 + self.mT85() + + + + elif alt35 == 62: + # C.g:1:254: T86 + self.mT86() + + + + elif alt35 == 63: + # C.g:1:258: T87 + self.mT87() + + + + elif alt35 == 64: + # C.g:1:262: T88 + self.mT88() + + + + elif alt35 == 65: + # C.g:1:266: T89 + self.mT89() + + + + elif alt35 == 66: + # C.g:1:270: T90 + self.mT90() + + + + elif alt35 == 67: + # C.g:1:274: T91 + self.mT91() + + + + elif alt35 == 68: + # C.g:1:278: T92 + self.mT92() + + + + elif alt35 == 69: + # C.g:1:282: T93 + self.mT93() + + + + elif alt35 == 70: + # C.g:1:286: T94 + self.mT94() + + + + elif alt35 == 71: + # C.g:1:290: T95 + self.mT95() + + + + elif alt35 == 72: + # C.g:1:294: T96 + self.mT96() + + + + elif alt35 == 73: + # C.g:1:298: T97 + self.mT97() + + + + elif alt35 == 74: + # C.g:1:302: T98 + self.mT98() + + + + elif alt35 == 75: + # C.g:1:306: T99 + self.mT99() + + + + elif alt35 == 76: + # C.g:1:310: T100 + self.mT100() + + + + elif alt35 == 77: + # C.g:1:315: T101 + self.mT101() + + + + elif alt35 == 78: + # C.g:1:320: T102 + self.mT102() + + + + elif alt35 == 79: + # C.g:1:325: T103 + self.mT103() + + + + elif alt35 == 80: + # C.g:1:330: T104 + self.mT104() + + + + elif alt35 == 81: + # C.g:1:335: T105 + self.mT105() + + + + elif alt35 == 82: + # C.g:1:340: T106 + self.mT106() + + + + elif alt35 == 83: + # C.g:1:345: T107 + self.mT107() + + + + elif alt35 == 84: + # C.g:1:350: T108 + self.mT108() + + + + elif alt35 == 85: + # C.g:1:355: T109 + self.mT109() + + + + elif alt35 == 86: + # C.g:1:360: T110 + self.mT110() + + + + elif alt35 == 87: + # C.g:1:365: T111 + self.mT111() + + + + elif alt35 == 88: + # C.g:1:370: T112 + self.mT112() + + + + elif alt35 == 89: + # C.g:1:375: T113 + self.mT113() + + + + elif alt35 == 90: + # C.g:1:380: T114 + self.mT114() + + + + elif alt35 == 91: + # C.g:1:385: T115 + self.mT115() + + + + elif alt35 == 92: + # C.g:1:390: T116 + self.mT116() + + + + elif alt35 == 93: + # C.g:1:395: IDENTIFIER + self.mIDENTIFIER() + + + + elif alt35 == 94: + # C.g:1:406: CHARACTER_LITERAL + self.mCHARACTER_LITERAL() + + + + elif alt35 == 95: + # C.g:1:424: STRING_LITERAL + self.mSTRING_LITERAL() + + + + elif alt35 == 96: + # C.g:1:439: HEX_LITERAL + self.mHEX_LITERAL() + + + + elif alt35 == 97: + # C.g:1:451: DECIMAL_LITERAL + self.mDECIMAL_LITERAL() + + + + elif alt35 == 98: + # C.g:1:467: OCTAL_LITERAL + self.mOCTAL_LITERAL() + + + + elif alt35 == 99: + # C.g:1:481: FLOATING_POINT_LITERAL + self.mFLOATING_POINT_LITERAL() + + + + elif alt35 == 100: + # C.g:1:504: WS + self.mWS() + + + + elif alt35 == 101: + # C.g:1:507: BS + self.mBS() + + + + elif alt35 == 102: + # C.g:1:510: UnicodeVocabulary + self.mUnicodeVocabulary() + + + + elif alt35 == 103: + # C.g:1:528: COMMENT + self.mCOMMENT() + + + + elif alt35 == 104: + # C.g:1:536: LINE_COMMENT + self.mLINE_COMMENT() + + + + elif alt35 == 105: + # C.g:1:549: LINE_COMMAND + self.mLINE_COMMAND() + + + + + + + + + # lookup tables for DFA #25 + + DFA25_eot = DFA.unpack( + u"\7\uffff\1\10\2\uffff" + ) + + DFA25_eof = DFA.unpack( + u"\12\uffff" + ) + + DFA25_min = DFA.unpack( + u"\2\56\1\uffff\1\53\2\uffff\2\60\2\uffff" + ) + + DFA25_max = DFA.unpack( + u"\1\71\1\146\1\uffff\1\71\2\uffff\1\71\1\146\2\uffff" + ) + + DFA25_accept = DFA.unpack( + u"\2\uffff\1\2\1\uffff\1\4\1\1\2\uffff\2\3" + ) + + DFA25_special = DFA.unpack( + u"\12\uffff" + ) + + + DFA25_transition = [ + DFA.unpack(u"\1\2\1\uffff\12\1"), + DFA.unpack(u"\1\5\1\uffff\12\1\12\uffff\1\4\1\3\1\4\35\uffff\1\4" + u"\1\3\1\4"), + DFA.unpack(u""), + DFA.unpack(u"\1\6\1\uffff\1\6\2\uffff\12\7"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\12\7"), + DFA.unpack(u"\12\7\12\uffff\1\11\1\uffff\1\11\35\uffff\1\11\1\uffff" + u"\1\11"), + DFA.unpack(u""), + DFA.unpack(u"") + ] + + # class definition for DFA #25 + + DFA25 = DFA + # lookup tables for DFA #35 + + DFA35_eot = DFA.unpack( + u"\2\uffff\1\75\1\uffff\1\100\14\75\3\uffff\7\75\4\uffff\1\147\1" + u"\151\1\155\1\161\1\165\1\167\1\172\1\uffff\1\175\1\u0080\1\u0083" + u"\1\u0085\1\u0088\1\uffff\5\75\1\uffff\2\72\2\u0092\2\uffff\1\72" + u"\2\uffff\1\75\4\uffff\16\75\1\u00ab\4\75\1\u00b1\2\75\3\uffff\1" + u"\u00b5\7\75\35\uffff\1\u00be\1\uffff\1\u00c0\10\uffff\5\75\4\uffff" + u"\1\u00c6\1\u0092\3\uffff\23\75\1\uffff\1\u00db\1\75\1\u00dd\2\75" + u"\1\uffff\3\75\1\uffff\1\u00e3\6\75\4\uffff\5\75\1\uffff\1\75\1" + u"\u00f1\1\u00f2\7\75\1\u00fa\3\75\1\u00fe\3\75\1\u0102\1\u0103\1" + u"\uffff\1\u0104\1\uffff\5\75\1\uffff\10\75\1\u0113\1\75\1\u0115" + u"\2\75\2\uffff\6\75\1\u011e\1\uffff\3\75\1\uffff\2\75\1\u0124\3" + u"\uffff\1\u0125\3\75\1\u0129\1\75\1\u012b\6\75\1\u0133\1\uffff\1" + u"\u0134\1\uffff\1\u0135\1\75\1\u0137\1\u0138\1\u0139\1\u013a\1\u013b" + u"\1\u013c\1\uffff\1\75\1\u013e\1\u013f\2\75\2\uffff\1\u0142\2\75" + u"\1\uffff\1\75\1\uffff\5\75\1\u014b\1\75\3\uffff\1\u014d\6\uffff" + u"\1\75\2\uffff\2\75\1\uffff\1\u0151\7\75\1\uffff\1\u0159\1\uffff" + u"\1\u015a\1\u015b\1\u015c\1\uffff\1\u015d\1\u015e\1\75\1\u0160\3" + u"\75\6\uffff\1\u0164\1\uffff\3\75\1\uffff\20\75\1\u0178\2\75\1\uffff" + u"\4\75\1\u017f\1\75\1\uffff\11\75\1\u018a\1\uffff" + ) + + DFA35_eof = DFA.unpack( + u"\u018b\uffff" + ) + + DFA35_min = DFA.unpack( + u"\1\3\1\uffff\1\171\1\uffff\1\75\1\154\1\150\1\165\1\145\1\124\1" + u"\157\1\141\1\146\1\157\1\154\1\145\1\156\3\uffff\1\116\1\120\1" + u"\117\1\116\1\117\1\114\1\106\4\uffff\1\75\1\56\1\53\1\55\1\52\1" + u"\75\1\46\1\uffff\1\75\1\74\3\75\1\uffff\1\137\1\150\1\157\1\162" + u"\1\42\1\uffff\2\0\2\56\2\uffff\1\0\2\uffff\1\160\4\uffff\1\165" + u"\1\163\1\164\1\141\1\151\1\147\1\157\1\164\1\147\1\101\1\151\1" + u"\156\1\163\1\141\1\44\1\164\1\156\1\162\1\157\1\44\1\146\1\151" + u"\3\uffff\1\44\2\124\1\116\1\101\1\114\1\117\1\111\35\uffff\1\75" + u"\1\uffff\1\75\10\uffff\1\141\1\163\1\151\1\164\1\145\4\uffff\2" + u"\56\3\uffff\1\145\1\155\2\145\1\165\2\164\1\156\1\145\1\162\1\157" + u"\1\151\1\165\1\124\1\144\1\141\1\163\1\145\1\162\1\uffff\1\44\1" + u"\147\1\44\1\141\1\142\1\uffff\1\141\1\151\1\157\1\uffff\1\44\1" + u"\111\1\123\1\114\1\101\1\102\1\101\4\uffff\1\163\1\155\1\154\1" + u"\157\1\141\1\uffff\1\144\2\44\1\162\1\143\1\151\1\143\1\145\1\157" + u"\1\164\1\44\1\163\1\162\1\111\1\44\1\164\1\151\1\164\2\44\1\uffff" + u"\1\44\1\uffff\1\164\1\154\1\165\1\147\1\156\1\uffff\1\117\1\124" + u"\1\111\1\124\1\101\1\102\1\120\1\155\1\44\1\145\1\44\1\153\1\145" + u"\2\uffff\1\156\1\164\1\143\1\150\1\144\1\146\1\44\1\uffff\1\164" + u"\1\156\1\103\1\uffff\1\151\1\156\1\44\3\uffff\1\44\1\145\1\154" + u"\1\156\1\44\1\116\1\44\1\107\1\111\1\114\1\117\1\125\1\111\1\44" + u"\1\uffff\1\44\1\uffff\1\44\1\146\6\44\1\uffff\1\145\2\44\1\154" + u"\1\165\2\uffff\1\44\1\164\1\145\1\uffff\1\101\1\uffff\1\116\1\114" + u"\1\137\1\117\1\116\1\44\1\137\3\uffff\1\44\6\uffff\1\162\2\uffff" + u"\2\145\1\uffff\1\44\1\144\1\114\2\105\1\122\2\124\1\uffff\1\44" + u"\1\uffff\3\44\1\uffff\2\44\1\104\1\44\1\105\1\123\1\111\6\uffff" + u"\1\44\1\uffff\1\115\1\105\1\115\1\uffff\1\117\1\122\1\105\2\126" + u"\1\123\1\105\1\111\1\105\1\137\1\103\1\122\1\111\1\105\1\126\1" + u"\106\1\44\1\111\1\137\1\uffff\1\103\1\125\1\105\1\116\1\44\1\122" + u"\1\uffff\1\105\1\106\1\105\1\122\1\105\1\116\1\103\1\105\1\104" + u"\1\44\1\uffff" + ) + + DFA35_max = DFA.unpack( + u"\1\ufffe\1\uffff\1\171\1\uffff\1\75\1\170\1\167\1\165\1\145\1\124" + u"\2\157\1\156\3\157\1\156\3\uffff\1\116\1\125\1\117\1\116\1\117" + u"\1\114\1\106\4\uffff\1\75\1\71\1\75\1\76\3\75\1\uffff\2\75\1\76" + u"\1\75\1\174\1\uffff\1\141\1\150\1\157\1\162\1\47\1\uffff\2\ufffe" + u"\1\170\1\146\2\uffff\1\ufffe\2\uffff\1\160\4\uffff\1\165\1\163" + u"\1\164\1\162\1\151\1\172\1\157\2\164\1\101\1\154\1\156\1\163\1" + u"\141\1\172\1\164\1\156\1\162\1\157\1\172\1\146\1\163\3\uffff\1" + u"\172\2\124\1\116\1\101\1\114\1\117\1\111\35\uffff\1\75\1\uffff" + u"\1\75\10\uffff\1\141\1\163\1\151\1\164\1\145\4\uffff\2\146\3\uffff" + u"\1\145\1\155\2\145\1\165\2\164\1\156\1\145\1\162\1\157\1\151\1" + u"\165\1\124\1\144\1\141\1\164\1\145\1\162\1\uffff\1\172\1\147\1" + u"\172\1\141\1\142\1\uffff\1\141\1\151\1\157\1\uffff\1\172\1\111" + u"\1\123\1\114\1\101\1\102\1\137\4\uffff\1\163\1\155\1\154\1\157" + u"\1\141\1\uffff\1\144\2\172\1\162\1\143\1\151\1\143\1\145\1\157" + u"\1\164\1\172\1\163\1\162\1\111\1\172\1\164\1\151\1\164\2\172\1" + u"\uffff\1\172\1\uffff\1\164\1\154\1\165\1\147\1\156\1\uffff\1\117" + u"\1\124\1\111\1\124\1\101\1\122\1\120\1\155\1\172\1\145\1\172\1" + u"\153\1\145\2\uffff\1\156\1\164\1\143\1\150\1\144\1\146\1\172\1" + u"\uffff\1\164\1\156\1\103\1\uffff\1\151\1\156\1\172\3\uffff\1\172" + u"\1\145\1\154\1\156\1\172\1\116\1\172\1\107\1\111\1\114\1\117\1" + u"\125\1\111\1\172\1\uffff\1\172\1\uffff\1\172\1\146\6\172\1\uffff" + u"\1\145\2\172\1\154\1\165\2\uffff\1\172\1\164\1\145\1\uffff\1\101" + u"\1\uffff\1\116\1\114\1\137\1\117\1\116\1\172\1\137\3\uffff\1\172" + u"\6\uffff\1\162\2\uffff\2\145\1\uffff\1\172\1\144\1\114\2\105\1" + u"\122\2\124\1\uffff\1\172\1\uffff\3\172\1\uffff\2\172\1\104\1\172" + u"\1\105\1\123\1\111\6\uffff\1\172\1\uffff\1\115\1\105\1\115\1\uffff" + u"\1\117\1\122\1\105\2\126\1\123\1\105\1\111\1\105\1\137\1\103\1" + u"\122\1\111\1\105\1\126\1\106\1\172\1\111\1\137\1\uffff\1\103\1" + u"\125\1\105\1\116\1\172\1\122\1\uffff\1\105\1\106\1\105\1\122\1" + u"\105\1\116\1\103\1\105\1\104\1\172\1\uffff" + ) + + DFA35_accept = DFA.unpack( + u"\1\uffff\1\1\1\uffff\1\3\15\uffff\1\23\1\24\1\27\7\uffff\1\45\1" + u"\46\1\47\1\50\7\uffff\1\65\5\uffff\1\101\5\uffff\1\135\4\uffff" + u"\1\144\1\145\1\uffff\1\146\1\1\1\uffff\1\135\1\3\1\106\1\4\26\uffff" + u"\1\23\1\24\1\27\10\uffff\1\45\1\46\1\47\1\50\1\67\1\51\1\52\1\62" + u"\1\143\1\57\1\72\1\53\1\63\1\73\1\60\1\54\1\70\1\150\1\147\1\55" + u"\1\71\1\56\1\76\1\103\1\64\1\65\1\107\1\66\1\112\1\uffff\1\110" + u"\1\uffff\1\113\1\111\1\77\1\105\1\100\1\102\1\104\1\101\5\uffff" + u"\1\136\1\137\1\140\1\141\2\uffff\1\144\1\145\1\151\23\uffff\1\123" + u"\5\uffff\1\127\3\uffff\1\33\7\uffff\1\74\1\114\1\75\1\115\5\uffff" + u"\1\142\24\uffff\1\15\1\uffff\1\130\5\uffff\1\34\15\uffff\1\30\1" + u"\124\7\uffff\1\7\3\uffff\1\12\3\uffff\1\121\1\13\1\16\16\uffff" + u"\1\117\1\uffff\1\131\10\uffff\1\14\5\uffff\1\31\1\17\3\uffff\1" + u"\26\1\uffff\1\36\7\uffff\1\120\1\126\1\133\1\uffff\1\5\1\25\1\6" + u"\1\125\1\21\1\61\1\uffff\1\134\1\11\2\uffff\1\20\10\uffff\1\42" + u"\1\uffff\1\2\3\uffff\1\122\7\uffff\1\116\1\10\1\32\1\132\1\22\1" + u"\35\1\uffff\1\40\3\uffff\1\37\23\uffff\1\43\6\uffff\1\44\12\uffff" + u"\1\41" + ) + + DFA35_special = DFA.unpack( + u"\u018b\uffff" + ) + + + DFA35_transition = [ + DFA.unpack(u"\6\72\2\67\1\72\2\67\22\72\1\67\1\47\1\64\1\71\1\62" + u"\1\44\1\45\1\63\1\33\1\34\1\37\1\41\1\3\1\42\1\40\1\43\1\65\11" + u"\66\1\23\1\1\1\50\1\4\1\51\1\54\1\72\2\62\1\26\1\62\1\32\1\62\1" + u"\31\1\62\1\24\2\62\1\61\2\62\1\25\3\62\1\11\1\62\1\27\1\30\4\62" + u"\1\35\1\70\1\36\1\52\1\55\1\72\1\7\1\60\1\13\1\17\1\5\1\16\1\57" + u"\1\62\1\14\2\62\1\15\5\62\1\10\1\6\1\2\1\20\1\12\1\56\3\62\1\21" + u"\1\53\1\22\1\46\uff80\72"), + DFA.unpack(u""), + DFA.unpack(u"\1\74"), + DFA.unpack(u""), + DFA.unpack(u"\1\77"), + DFA.unpack(u"\1\102\1\uffff\1\101\11\uffff\1\103"), + DFA.unpack(u"\1\107\1\106\12\uffff\1\104\2\uffff\1\105"), + DFA.unpack(u"\1\110"), + DFA.unpack(u"\1\111"), + DFA.unpack(u"\1\112"), + DFA.unpack(u"\1\113"), + DFA.unpack(u"\1\115\6\uffff\1\116\6\uffff\1\114"), + DFA.unpack(u"\1\117\7\uffff\1\120"), + DFA.unpack(u"\1\121"), + DFA.unpack(u"\1\123\2\uffff\1\122"), + DFA.unpack(u"\1\125\11\uffff\1\124"), + DFA.unpack(u"\1\126"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\132"), + DFA.unpack(u"\1\134\4\uffff\1\133"), + DFA.unpack(u"\1\135"), + DFA.unpack(u"\1\136"), + DFA.unpack(u"\1\137"), + DFA.unpack(u"\1\140"), + DFA.unpack(u"\1\141"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\146"), + DFA.unpack(u"\1\150\1\uffff\12\152"), + DFA.unpack(u"\1\153\21\uffff\1\154"), + DFA.unpack(u"\1\160\17\uffff\1\157\1\156"), + DFA.unpack(u"\1\164\4\uffff\1\163\15\uffff\1\162"), + DFA.unpack(u"\1\166"), + DFA.unpack(u"\1\171\26\uffff\1\170"), + DFA.unpack(u""), + DFA.unpack(u"\1\174"), + DFA.unpack(u"\1\177\1\176"), + DFA.unpack(u"\1\u0082\1\u0081"), + DFA.unpack(u"\1\u0084"), + DFA.unpack(u"\1\u0086\76\uffff\1\u0087"), + DFA.unpack(u""), + DFA.unpack(u"\1\u008a\1\uffff\1\u008b"), + DFA.unpack(u"\1\u008c"), + DFA.unpack(u"\1\u008d"), + DFA.unpack(u"\1\u008e"), + DFA.unpack(u"\1\u0090\4\uffff\1\u008f"), + DFA.unpack(u""), + DFA.unpack(u"\47\u008f\1\uffff\uffd7\u008f"), + DFA.unpack(u"\uffff\u0090"), + DFA.unpack(u"\1\152\1\uffff\10\u0093\2\152\12\uffff\3\152\21\uffff" + u"\1\u0091\13\uffff\3\152\21\uffff\1\u0091"), + DFA.unpack(u"\1\152\1\uffff\12\u0094\12\uffff\3\152\35\uffff\3\152"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\uffff\u0097"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\u0098"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\u0099"), + DFA.unpack(u"\1\u009a"), + DFA.unpack(u"\1\u009b"), + DFA.unpack(u"\1\u009d\20\uffff\1\u009c"), + DFA.unpack(u"\1\u009e"), + DFA.unpack(u"\1\u009f\22\uffff\1\u00a0"), + DFA.unpack(u"\1\u00a1"), + DFA.unpack(u"\1\u00a2"), + DFA.unpack(u"\1\u00a3\14\uffff\1\u00a4"), + DFA.unpack(u"\1\u00a5"), + DFA.unpack(u"\1\u00a6\2\uffff\1\u00a7"), + DFA.unpack(u"\1\u00a8"), + DFA.unpack(u"\1\u00a9"), + DFA.unpack(u"\1\u00aa"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\u00ac"), + DFA.unpack(u"\1\u00ad"), + DFA.unpack(u"\1\u00ae"), + DFA.unpack(u"\1\u00af"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\24\75\1\u00b0\5\75"), + DFA.unpack(u"\1\u00b2"), + DFA.unpack(u"\1\u00b4\11\uffff\1\u00b3"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\u00b6"), + DFA.unpack(u"\1\u00b7"), + DFA.unpack(u"\1\u00b8"), + DFA.unpack(u"\1\u00b9"), + DFA.unpack(u"\1\u00ba"), + DFA.unpack(u"\1\u00bb"), + DFA.unpack(u"\1\u00bc"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\u00bd"), + DFA.unpack(u""), + DFA.unpack(u"\1\u00bf"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\u00c1"), + DFA.unpack(u"\1\u00c2"), + DFA.unpack(u"\1\u00c3"), + DFA.unpack(u"\1\u00c4"), + DFA.unpack(u"\1\u00c5"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\152\1\uffff\10\u0093\2\152\12\uffff\3\152\35\uffff" + u"\3\152"), + DFA.unpack(u"\1\152\1\uffff\12\u0094\12\uffff\3\152\35\uffff\3\152"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\u00c7"), + DFA.unpack(u"\1\u00c8"), + DFA.unpack(u"\1\u00c9"), + DFA.unpack(u"\1\u00ca"), + DFA.unpack(u"\1\u00cb"), + DFA.unpack(u"\1\u00cc"), + DFA.unpack(u"\1\u00cd"), + DFA.unpack(u"\1\u00ce"), + DFA.unpack(u"\1\u00cf"), + DFA.unpack(u"\1\u00d0"), + DFA.unpack(u"\1\u00d1"), + DFA.unpack(u"\1\u00d2"), + DFA.unpack(u"\1\u00d3"), + DFA.unpack(u"\1\u00d4"), + DFA.unpack(u"\1\u00d5"), + DFA.unpack(u"\1\u00d6"), + DFA.unpack(u"\1\u00d8\1\u00d7"), + DFA.unpack(u"\1\u00d9"), + DFA.unpack(u"\1\u00da"), + DFA.unpack(u""), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\u00dc"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\u00de"), + DFA.unpack(u"\1\u00df"), + DFA.unpack(u""), + DFA.unpack(u"\1\u00e0"), + DFA.unpack(u"\1\u00e1"), + DFA.unpack(u"\1\u00e2"), + DFA.unpack(u""), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\u00e4"), + DFA.unpack(u"\1\u00e5"), + DFA.unpack(u"\1\u00e6"), + DFA.unpack(u"\1\u00e7"), + DFA.unpack(u"\1\u00e8"), + DFA.unpack(u"\1\u00ea\35\uffff\1\u00e9"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\u00eb"), + DFA.unpack(u"\1\u00ec"), + DFA.unpack(u"\1\u00ed"), + DFA.unpack(u"\1\u00ee"), + DFA.unpack(u"\1\u00ef"), + DFA.unpack(u""), + DFA.unpack(u"\1\u00f0"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\u00f3"), + DFA.unpack(u"\1\u00f4"), + DFA.unpack(u"\1\u00f5"), + DFA.unpack(u"\1\u00f6"), + DFA.unpack(u"\1\u00f7"), + DFA.unpack(u"\1\u00f8"), + DFA.unpack(u"\1\u00f9"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\u00fb"), + DFA.unpack(u"\1\u00fc"), + DFA.unpack(u"\1\u00fd"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\u00ff"), + DFA.unpack(u"\1\u0100"), + DFA.unpack(u"\1\u0101"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u""), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u""), + DFA.unpack(u"\1\u0105"), + DFA.unpack(u"\1\u0106"), + DFA.unpack(u"\1\u0107"), + DFA.unpack(u"\1\u0108"), + DFA.unpack(u"\1\u0109"), + DFA.unpack(u""), + DFA.unpack(u"\1\u010a"), + DFA.unpack(u"\1\u010b"), + DFA.unpack(u"\1\u010c"), + DFA.unpack(u"\1\u010d"), + DFA.unpack(u"\1\u010e"), + DFA.unpack(u"\1\u010f\17\uffff\1\u0110"), + DFA.unpack(u"\1\u0111"), + DFA.unpack(u"\1\u0112"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\u0114"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\u0116"), + DFA.unpack(u"\1\u0117"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\u0118"), + DFA.unpack(u"\1\u0119"), + DFA.unpack(u"\1\u011a"), + DFA.unpack(u"\1\u011b"), + DFA.unpack(u"\1\u011c"), + DFA.unpack(u"\1\u011d"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u""), + DFA.unpack(u"\1\u011f"), + DFA.unpack(u"\1\u0120"), + DFA.unpack(u"\1\u0121"), + DFA.unpack(u""), + DFA.unpack(u"\1\u0122"), + DFA.unpack(u"\1\u0123"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\u0126"), + DFA.unpack(u"\1\u0127"), + DFA.unpack(u"\1\u0128"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\u012a"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\u012c"), + DFA.unpack(u"\1\u012d"), + DFA.unpack(u"\1\u012e"), + DFA.unpack(u"\1\u012f"), + DFA.unpack(u"\1\u0130"), + DFA.unpack(u"\1\u0131"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\u0132\1" + u"\uffff\32\75"), + DFA.unpack(u""), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u""), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\u0136"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u""), + DFA.unpack(u"\1\u013d"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\u0140"), + DFA.unpack(u"\1\u0141"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\u0143"), + DFA.unpack(u"\1\u0144"), + DFA.unpack(u""), + DFA.unpack(u"\1\u0145"), + DFA.unpack(u""), + DFA.unpack(u"\1\u0146"), + DFA.unpack(u"\1\u0147"), + DFA.unpack(u"\1\u0148"), + DFA.unpack(u"\1\u0149"), + DFA.unpack(u"\1\u014a"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\u014c"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\u014e"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\u014f"), + DFA.unpack(u"\1\u0150"), + DFA.unpack(u""), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\u0152"), + DFA.unpack(u"\1\u0153"), + DFA.unpack(u"\1\u0154"), + DFA.unpack(u"\1\u0155"), + DFA.unpack(u"\1\u0156"), + DFA.unpack(u"\1\u0157"), + DFA.unpack(u"\1\u0158"), + DFA.unpack(u""), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u""), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u""), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\u015f"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\u0161"), + DFA.unpack(u"\1\u0162"), + DFA.unpack(u"\1\u0163"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u""), + DFA.unpack(u"\1\u0165"), + DFA.unpack(u"\1\u0166"), + DFA.unpack(u"\1\u0167"), + DFA.unpack(u""), + DFA.unpack(u"\1\u0168"), + DFA.unpack(u"\1\u0169"), + DFA.unpack(u"\1\u016a"), + DFA.unpack(u"\1\u016b"), + DFA.unpack(u"\1\u016c"), + DFA.unpack(u"\1\u016d"), + DFA.unpack(u"\1\u016e"), + DFA.unpack(u"\1\u016f"), + DFA.unpack(u"\1\u0170"), + DFA.unpack(u"\1\u0171"), + DFA.unpack(u"\1\u0172"), + DFA.unpack(u"\1\u0173"), + DFA.unpack(u"\1\u0174"), + DFA.unpack(u"\1\u0175"), + DFA.unpack(u"\1\u0176"), + DFA.unpack(u"\1\u0177"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\u0179"), + DFA.unpack(u"\1\u017a"), + DFA.unpack(u""), + DFA.unpack(u"\1\u017b"), + DFA.unpack(u"\1\u017c"), + DFA.unpack(u"\1\u017d"), + DFA.unpack(u"\1\u017e"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"\1\u0180"), + DFA.unpack(u""), + DFA.unpack(u"\1\u0181"), + DFA.unpack(u"\1\u0182"), + DFA.unpack(u"\1\u0183"), + DFA.unpack(u"\1\u0184"), + DFA.unpack(u"\1\u0185"), + DFA.unpack(u"\1\u0186"), + DFA.unpack(u"\1\u0187"), + DFA.unpack(u"\1\u0188"), + DFA.unpack(u"\1\u0189"), + DFA.unpack(u"\1\75\13\uffff\12\75\7\uffff\32\75\4\uffff\1\75\1\uffff" + u"\32\75"), + DFA.unpack(u"") + ] + + # class definition for DFA #35 + + DFA35 = DFA + + diff --git a/BaseTools/Source/Python/Ecc/CParser.py b/BaseTools/Source/Python/Ecc/CParser.py new file mode 100644 index 0000000000..194a6aa451 --- /dev/null +++ b/BaseTools/Source/Python/Ecc/CParser.py @@ -0,0 +1,18825 @@ +# $ANTLR 3.0.1 C.g 2009-02-16 16:02:50 + +from antlr3 import * +from antlr3.compat import set, frozenset + +import CodeFragment +import FileProfile + + + +# for convenience in actions +HIDDEN = BaseRecognizer.HIDDEN + +# token types +CHARACTER_LITERAL=8 +LETTER=11 +Exponent=15 +DECIMAL_LITERAL=7 +IntegerTypeSuffix=14 +UnicodeVocabulary=21 +HexDigit=13 +BS=20 +WS=19 +LINE_COMMAND=24 +COMMENT=22 +LINE_COMMENT=23 +OCTAL_LITERAL=6 +HEX_LITERAL=5 +FLOATING_POINT_LITERAL=10 +UnicodeEscape=18 +EscapeSequence=12 +EOF=-1 +STRING_LITERAL=9 +OctalEscape=17 +IDENTIFIER=4 +FloatTypeSuffix=16 + +# token names +tokenNames = [ + "", "", "", "", + "IDENTIFIER", "HEX_LITERAL", "OCTAL_LITERAL", "DECIMAL_LITERAL", "CHARACTER_LITERAL", + "STRING_LITERAL", "FLOATING_POINT_LITERAL", "LETTER", "EscapeSequence", + "HexDigit", "IntegerTypeSuffix", "Exponent", "FloatTypeSuffix", "OctalEscape", + "UnicodeEscape", "WS", "BS", "UnicodeVocabulary", "COMMENT", "LINE_COMMENT", + "LINE_COMMAND", "';'", "'typedef'", "','", "'='", "'extern'", "'static'", + "'auto'", "'register'", "'STATIC'", "'void'", "'char'", "'short'", "'int'", + "'long'", "'float'", "'double'", "'signed'", "'unsigned'", "'{'", "'}'", + "'struct'", "'union'", "':'", "'enum'", "'const'", "'volatile'", "'IN'", + "'OUT'", "'OPTIONAL'", "'CONST'", "'UNALIGNED'", "'VOLATILE'", "'GLOBAL_REMOVE_IF_UNREFERENCED'", + "'EFIAPI'", "'EFI_BOOTSERVICE'", "'EFI_RUNTIMESERVICE'", "'('", "')'", + "'['", "']'", "'*'", "'...'", "'+'", "'-'", "'/'", "'%'", "'++'", "'--'", + "'sizeof'", "'.'", "'->'", "'&'", "'~'", "'!'", "'*='", "'/='", "'%='", + "'+='", "'-='", "'<<='", "'>>='", "'&='", "'^='", "'|='", "'?'", "'||'", + "'&&'", "'|'", "'^'", "'=='", "'!='", "'<'", "'>'", "'<='", "'>='", + "'<<'", "'>>'", "'__asm__'", "'_asm'", "'__asm'", "'case'", "'default'", + "'if'", "'else'", "'switch'", "'while'", "'do'", "'for'", "'goto'", + "'continue'", "'break'", "'return'" +] + + +class function_definition_scope(object): + def __init__(self): + self.ModifierText = None + self.DeclText = None + self.LBLine = None + self.LBOffset = None + self.DeclLine = None + self.DeclOffset = None +class postfix_expression_scope(object): + def __init__(self): + self.FuncCallText = None + + +class CParser(Parser): + grammarFileName = "C.g" + tokenNames = tokenNames + + def __init__(self, input): + Parser.__init__(self, input) + self.ruleMemo = {} + + self.function_definition_stack = [] + self.postfix_expression_stack = [] + + + + + + + + + def printTokenInfo(self, line, offset, tokenText): + print str(line)+ ',' + str(offset) + ':' + str(tokenText) + + def StorePredicateExpression(self, StartLine, StartOffset, EndLine, EndOffset, Text): + PredExp = CodeFragment.PredicateExpression(Text, (StartLine, StartOffset), (EndLine, EndOffset)) + FileProfile.PredicateExpressionList.append(PredExp) + + def StoreEnumerationDefinition(self, StartLine, StartOffset, EndLine, EndOffset, Text): + EnumDef = CodeFragment.EnumerationDefinition(Text, (StartLine, StartOffset), (EndLine, EndOffset)) + FileProfile.EnumerationDefinitionList.append(EnumDef) + + def StoreStructUnionDefinition(self, StartLine, StartOffset, EndLine, EndOffset, Text): + SUDef = CodeFragment.StructUnionDefinition(Text, (StartLine, StartOffset), (EndLine, EndOffset)) + FileProfile.StructUnionDefinitionList.append(SUDef) + + def StoreTypedefDefinition(self, StartLine, StartOffset, EndLine, EndOffset, FromText, ToText): + Tdef = CodeFragment.TypedefDefinition(FromText, ToText, (StartLine, StartOffset), (EndLine, EndOffset)) + FileProfile.TypedefDefinitionList.append(Tdef) + + def StoreFunctionDefinition(self, StartLine, StartOffset, EndLine, EndOffset, ModifierText, DeclText, LeftBraceLine, LeftBraceOffset, DeclLine, DeclOffset): + FuncDef = CodeFragment.FunctionDefinition(ModifierText, DeclText, (StartLine, StartOffset), (EndLine, EndOffset), (LeftBraceLine, LeftBraceOffset), (DeclLine, DeclOffset)) + FileProfile.FunctionDefinitionList.append(FuncDef) + + def StoreVariableDeclaration(self, StartLine, StartOffset, EndLine, EndOffset, ModifierText, DeclText): + VarDecl = CodeFragment.VariableDeclaration(ModifierText, DeclText, (StartLine, StartOffset), (EndLine, EndOffset)) + FileProfile.VariableDeclarationList.append(VarDecl) + + def StoreFunctionCalling(self, StartLine, StartOffset, EndLine, EndOffset, FuncName, ParamList): + FuncCall = CodeFragment.FunctionCalling(FuncName, ParamList, (StartLine, StartOffset), (EndLine, EndOffset)) + FileProfile.FunctionCallingList.append(FuncCall) + + + + + # $ANTLR start translation_unit + # C.g:50:1: translation_unit : ( external_declaration )* ; + def translation_unit(self, ): + + translation_unit_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 1): + return + + # C.g:51:2: ( ( external_declaration )* ) + # C.g:51:4: ( external_declaration )* + # C.g:51:4: ( external_declaration )* + while True: #loop1 + alt1 = 2 + LA1_0 = self.input.LA(1) + + if (LA1_0 == IDENTIFIER or LA1_0 == 26 or (29 <= LA1_0 <= 42) or (45 <= LA1_0 <= 46) or (48 <= LA1_0 <= 61) or LA1_0 == 65) : + alt1 = 1 + + + if alt1 == 1: + # C.g:0:0: external_declaration + self.following.append(self.FOLLOW_external_declaration_in_translation_unit64) + self.external_declaration() + self.following.pop() + if self.failed: + return + + + else: + break #loop1 + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 1, translation_unit_StartIndex) + + pass + + return + + # $ANTLR end translation_unit + + + # $ANTLR start external_declaration + # C.g:62:1: external_declaration options {k=1; } : ( ( ( declaration_specifiers )? declarator ( declaration )* '{' )=> function_definition | declaration | macro_statement ( ';' )? ); + def external_declaration(self, ): + + external_declaration_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 2): + return + + # C.g:67:2: ( ( ( declaration_specifiers )? declarator ( declaration )* '{' )=> function_definition | declaration | macro_statement ( ';' )? ) + alt3 = 3 + LA3_0 = self.input.LA(1) + + if ((29 <= LA3_0 <= 33)) : + LA3_1 = self.input.LA(2) + + if (self.synpred4()) : + alt3 = 1 + elif (self.synpred5()) : + alt3 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("62:1: external_declaration options {k=1; } : ( ( ( declaration_specifiers )? declarator ( declaration )* '{' )=> function_definition | declaration | macro_statement ( ';' )? );", 3, 1, self.input) + + raise nvae + + elif (LA3_0 == 34) : + LA3_2 = self.input.LA(2) + + if (self.synpred4()) : + alt3 = 1 + elif (self.synpred5()) : + alt3 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("62:1: external_declaration options {k=1; } : ( ( ( declaration_specifiers )? declarator ( declaration )* '{' )=> function_definition | declaration | macro_statement ( ';' )? );", 3, 2, self.input) + + raise nvae + + elif (LA3_0 == 35) : + LA3_3 = self.input.LA(2) + + if (self.synpred4()) : + alt3 = 1 + elif (self.synpred5()) : + alt3 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("62:1: external_declaration options {k=1; } : ( ( ( declaration_specifiers )? declarator ( declaration )* '{' )=> function_definition | declaration | macro_statement ( ';' )? );", 3, 3, self.input) + + raise nvae + + elif (LA3_0 == 36) : + LA3_4 = self.input.LA(2) + + if (self.synpred4()) : + alt3 = 1 + elif (self.synpred5()) : + alt3 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("62:1: external_declaration options {k=1; } : ( ( ( declaration_specifiers )? declarator ( declaration )* '{' )=> function_definition | declaration | macro_statement ( ';' )? );", 3, 4, self.input) + + raise nvae + + elif (LA3_0 == 37) : + LA3_5 = self.input.LA(2) + + if (self.synpred4()) : + alt3 = 1 + elif (self.synpred5()) : + alt3 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("62:1: external_declaration options {k=1; } : ( ( ( declaration_specifiers )? declarator ( declaration )* '{' )=> function_definition | declaration | macro_statement ( ';' )? );", 3, 5, self.input) + + raise nvae + + elif (LA3_0 == 38) : + LA3_6 = self.input.LA(2) + + if (self.synpred4()) : + alt3 = 1 + elif (self.synpred5()) : + alt3 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("62:1: external_declaration options {k=1; } : ( ( ( declaration_specifiers )? declarator ( declaration )* '{' )=> function_definition | declaration | macro_statement ( ';' )? );", 3, 6, self.input) + + raise nvae + + elif (LA3_0 == 39) : + LA3_7 = self.input.LA(2) + + if (self.synpred4()) : + alt3 = 1 + elif (self.synpred5()) : + alt3 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("62:1: external_declaration options {k=1; } : ( ( ( declaration_specifiers )? declarator ( declaration )* '{' )=> function_definition | declaration | macro_statement ( ';' )? );", 3, 7, self.input) + + raise nvae + + elif (LA3_0 == 40) : + LA3_8 = self.input.LA(2) + + if (self.synpred4()) : + alt3 = 1 + elif (self.synpred5()) : + alt3 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("62:1: external_declaration options {k=1; } : ( ( ( declaration_specifiers )? declarator ( declaration )* '{' )=> function_definition | declaration | macro_statement ( ';' )? );", 3, 8, self.input) + + raise nvae + + elif (LA3_0 == 41) : + LA3_9 = self.input.LA(2) + + if (self.synpred4()) : + alt3 = 1 + elif (self.synpred5()) : + alt3 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("62:1: external_declaration options {k=1; } : ( ( ( declaration_specifiers )? declarator ( declaration )* '{' )=> function_definition | declaration | macro_statement ( ';' )? );", 3, 9, self.input) + + raise nvae + + elif (LA3_0 == 42) : + LA3_10 = self.input.LA(2) + + if (self.synpred4()) : + alt3 = 1 + elif (self.synpred5()) : + alt3 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("62:1: external_declaration options {k=1; } : ( ( ( declaration_specifiers )? declarator ( declaration )* '{' )=> function_definition | declaration | macro_statement ( ';' )? );", 3, 10, self.input) + + raise nvae + + elif ((45 <= LA3_0 <= 46)) : + LA3_11 = self.input.LA(2) + + if (self.synpred4()) : + alt3 = 1 + elif (self.synpred5()) : + alt3 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("62:1: external_declaration options {k=1; } : ( ( ( declaration_specifiers )? declarator ( declaration )* '{' )=> function_definition | declaration | macro_statement ( ';' )? );", 3, 11, self.input) + + raise nvae + + elif (LA3_0 == 48) : + LA3_12 = self.input.LA(2) + + if (self.synpred4()) : + alt3 = 1 + elif (self.synpred5()) : + alt3 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("62:1: external_declaration options {k=1; } : ( ( ( declaration_specifiers )? declarator ( declaration )* '{' )=> function_definition | declaration | macro_statement ( ';' )? );", 3, 12, self.input) + + raise nvae + + elif (LA3_0 == IDENTIFIER) : + LA3_13 = self.input.LA(2) + + if (self.synpred4()) : + alt3 = 1 + elif (self.synpred5()) : + alt3 = 2 + elif (True) : + alt3 = 3 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("62:1: external_declaration options {k=1; } : ( ( ( declaration_specifiers )? declarator ( declaration )* '{' )=> function_definition | declaration | macro_statement ( ';' )? );", 3, 13, self.input) + + raise nvae + + elif (LA3_0 == 58) : + LA3_14 = self.input.LA(2) + + if (self.synpred4()) : + alt3 = 1 + elif (self.synpred5()) : + alt3 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("62:1: external_declaration options {k=1; } : ( ( ( declaration_specifiers )? declarator ( declaration )* '{' )=> function_definition | declaration | macro_statement ( ';' )? );", 3, 14, self.input) + + raise nvae + + elif (LA3_0 == 65) and (self.synpred4()): + alt3 = 1 + elif (LA3_0 == 59) : + LA3_16 = self.input.LA(2) + + if (self.synpred4()) : + alt3 = 1 + elif (self.synpred5()) : + alt3 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("62:1: external_declaration options {k=1; } : ( ( ( declaration_specifiers )? declarator ( declaration )* '{' )=> function_definition | declaration | macro_statement ( ';' )? );", 3, 16, self.input) + + raise nvae + + elif (LA3_0 == 60) : + LA3_17 = self.input.LA(2) + + if (self.synpred4()) : + alt3 = 1 + elif (self.synpred5()) : + alt3 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("62:1: external_declaration options {k=1; } : ( ( ( declaration_specifiers )? declarator ( declaration )* '{' )=> function_definition | declaration | macro_statement ( ';' )? );", 3, 17, self.input) + + raise nvae + + elif ((49 <= LA3_0 <= 57)) : + LA3_18 = self.input.LA(2) + + if (self.synpred4()) : + alt3 = 1 + elif (self.synpred5()) : + alt3 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("62:1: external_declaration options {k=1; } : ( ( ( declaration_specifiers )? declarator ( declaration )* '{' )=> function_definition | declaration | macro_statement ( ';' )? );", 3, 18, self.input) + + raise nvae + + elif (LA3_0 == 61) and (self.synpred4()): + alt3 = 1 + elif (LA3_0 == 26) : + alt3 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("62:1: external_declaration options {k=1; } : ( ( ( declaration_specifiers )? declarator ( declaration )* '{' )=> function_definition | declaration | macro_statement ( ';' )? );", 3, 0, self.input) + + raise nvae + + if alt3 == 1: + # C.g:67:4: ( ( declaration_specifiers )? declarator ( declaration )* '{' )=> function_definition + self.following.append(self.FOLLOW_function_definition_in_external_declaration103) + self.function_definition() + self.following.pop() + if self.failed: + return + + + elif alt3 == 2: + # C.g:68:4: declaration + self.following.append(self.FOLLOW_declaration_in_external_declaration108) + self.declaration() + self.following.pop() + if self.failed: + return + + + elif alt3 == 3: + # C.g:69:4: macro_statement ( ';' )? + self.following.append(self.FOLLOW_macro_statement_in_external_declaration113) + self.macro_statement() + self.following.pop() + if self.failed: + return + # C.g:69:20: ( ';' )? + alt2 = 2 + LA2_0 = self.input.LA(1) + + if (LA2_0 == 25) : + alt2 = 1 + if alt2 == 1: + # C.g:69:21: ';' + self.match(self.input, 25, self.FOLLOW_25_in_external_declaration116) + if self.failed: + return + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 2, external_declaration_StartIndex) + + pass + + return + + # $ANTLR end external_declaration + + class function_definition_return(object): + def __init__(self): + self.start = None + self.stop = None + + + + # $ANTLR start function_definition + # C.g:74:1: function_definition : (d= declaration_specifiers )? declarator ( ( declaration )+ a= compound_statement | b= compound_statement ) ; + def function_definition(self, ): + self.function_definition_stack.append(function_definition_scope()) + retval = self.function_definition_return() + retval.start = self.input.LT(1) + function_definition_StartIndex = self.input.index() + d = None + + a = None + + b = None + + declarator1 = None + + + + self.function_definition_stack[-1].ModifierText = '' + self.function_definition_stack[-1].DeclText = '' + self.function_definition_stack[-1].LBLine = 0 + self.function_definition_stack[-1].LBOffset = 0 + self.function_definition_stack[-1].DeclLine = 0 + self.function_definition_stack[-1].DeclOffset = 0 + + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 3): + return retval + + # C.g:94:2: ( (d= declaration_specifiers )? declarator ( ( declaration )+ a= compound_statement | b= compound_statement ) ) + # C.g:94:4: (d= declaration_specifiers )? declarator ( ( declaration )+ a= compound_statement | b= compound_statement ) + # C.g:94:5: (d= declaration_specifiers )? + alt4 = 2 + LA4 = self.input.LA(1) + if LA4 == 29 or LA4 == 30 or LA4 == 31 or LA4 == 32 or LA4 == 33 or LA4 == 34 or LA4 == 35 or LA4 == 36 or LA4 == 37 or LA4 == 38 or LA4 == 39 or LA4 == 40 or LA4 == 41 or LA4 == 42 or LA4 == 45 or LA4 == 46 or LA4 == 48 or LA4 == 49 or LA4 == 50 or LA4 == 51 or LA4 == 52 or LA4 == 53 or LA4 == 54 or LA4 == 55 or LA4 == 56 or LA4 == 57: + alt4 = 1 + elif LA4 == IDENTIFIER: + LA4 = self.input.LA(2) + if LA4 == 65: + alt4 = 1 + elif LA4 == 58: + LA4_21 = self.input.LA(3) + + if (self.synpred7()) : + alt4 = 1 + elif LA4 == 59: + LA4_22 = self.input.LA(3) + + if (self.synpred7()) : + alt4 = 1 + elif LA4 == 60: + LA4_23 = self.input.LA(3) + + if (self.synpred7()) : + alt4 = 1 + elif LA4 == IDENTIFIER: + LA4_24 = self.input.LA(3) + + if (self.synpred7()) : + alt4 = 1 + elif LA4 == 61: + LA4_25 = self.input.LA(3) + + if (self.synpred7()) : + alt4 = 1 + elif LA4 == 29 or LA4 == 30 or LA4 == 31 or LA4 == 32 or LA4 == 33: + LA4_26 = self.input.LA(3) + + if (self.synpred7()) : + alt4 = 1 + elif LA4 == 34: + LA4_27 = self.input.LA(3) + + if (self.synpred7()) : + alt4 = 1 + elif LA4 == 35: + LA4_28 = self.input.LA(3) + + if (self.synpred7()) : + alt4 = 1 + elif LA4 == 36: + LA4_29 = self.input.LA(3) + + if (self.synpred7()) : + alt4 = 1 + elif LA4 == 37: + LA4_30 = self.input.LA(3) + + if (self.synpred7()) : + alt4 = 1 + elif LA4 == 38: + LA4_31 = self.input.LA(3) + + if (self.synpred7()) : + alt4 = 1 + elif LA4 == 39: + LA4_32 = self.input.LA(3) + + if (self.synpred7()) : + alt4 = 1 + elif LA4 == 40: + LA4_33 = self.input.LA(3) + + if (self.synpred7()) : + alt4 = 1 + elif LA4 == 41: + LA4_34 = self.input.LA(3) + + if (self.synpred7()) : + alt4 = 1 + elif LA4 == 42: + LA4_35 = self.input.LA(3) + + if (self.synpred7()) : + alt4 = 1 + elif LA4 == 45 or LA4 == 46: + LA4_36 = self.input.LA(3) + + if (self.synpred7()) : + alt4 = 1 + elif LA4 == 48: + LA4_37 = self.input.LA(3) + + if (self.synpred7()) : + alt4 = 1 + elif LA4 == 49 or LA4 == 50 or LA4 == 51 or LA4 == 52 or LA4 == 53 or LA4 == 54 or LA4 == 55 or LA4 == 56 or LA4 == 57: + LA4_38 = self.input.LA(3) + + if (self.synpred7()) : + alt4 = 1 + elif LA4 == 58: + LA4_14 = self.input.LA(2) + + if (self.synpred7()) : + alt4 = 1 + elif LA4 == 59: + LA4_16 = self.input.LA(2) + + if (self.synpred7()) : + alt4 = 1 + elif LA4 == 60: + LA4_17 = self.input.LA(2) + + if (self.synpred7()) : + alt4 = 1 + if alt4 == 1: + # C.g:0:0: d= declaration_specifiers + self.following.append(self.FOLLOW_declaration_specifiers_in_function_definition147) + d = self.declaration_specifiers() + self.following.pop() + if self.failed: + return retval + + + + self.following.append(self.FOLLOW_declarator_in_function_definition150) + declarator1 = self.declarator() + self.following.pop() + if self.failed: + return retval + # C.g:95:3: ( ( declaration )+ a= compound_statement | b= compound_statement ) + alt6 = 2 + LA6_0 = self.input.LA(1) + + if (LA6_0 == IDENTIFIER or LA6_0 == 26 or (29 <= LA6_0 <= 42) or (45 <= LA6_0 <= 46) or (48 <= LA6_0 <= 60)) : + alt6 = 1 + elif (LA6_0 == 43) : + alt6 = 2 + else: + if self.backtracking > 0: + self.failed = True + return retval + + nvae = NoViableAltException("95:3: ( ( declaration )+ a= compound_statement | b= compound_statement )", 6, 0, self.input) + + raise nvae + + if alt6 == 1: + # C.g:95:5: ( declaration )+ a= compound_statement + # C.g:95:5: ( declaration )+ + cnt5 = 0 + while True: #loop5 + alt5 = 2 + LA5_0 = self.input.LA(1) + + if (LA5_0 == IDENTIFIER or LA5_0 == 26 or (29 <= LA5_0 <= 42) or (45 <= LA5_0 <= 46) or (48 <= LA5_0 <= 60)) : + alt5 = 1 + + + if alt5 == 1: + # C.g:0:0: declaration + self.following.append(self.FOLLOW_declaration_in_function_definition156) + self.declaration() + self.following.pop() + if self.failed: + return retval + + + else: + if cnt5 >= 1: + break #loop5 + + if self.backtracking > 0: + self.failed = True + return retval + + eee = EarlyExitException(5, self.input) + raise eee + + cnt5 += 1 + + + self.following.append(self.FOLLOW_compound_statement_in_function_definition161) + a = self.compound_statement() + self.following.pop() + if self.failed: + return retval + + + elif alt6 == 2: + # C.g:96:5: b= compound_statement + self.following.append(self.FOLLOW_compound_statement_in_function_definition170) + b = self.compound_statement() + self.following.pop() + if self.failed: + return retval + + + + if self.backtracking == 0: + + if d != None: + self.function_definition_stack[-1].ModifierText = self.input.toString(d.start,d.stop) + else: + self.function_definition_stack[-1].ModifierText = '' + self.function_definition_stack[-1].DeclText = self.input.toString(declarator1.start,declarator1.stop) + self.function_definition_stack[-1].DeclLine = declarator1.start.line + self.function_definition_stack[-1].DeclOffset = declarator1.start.charPositionInLine + if a != None: + self.function_definition_stack[-1].LBLine = a.start.line + self.function_definition_stack[-1].LBOffset = a.start.charPositionInLine + else: + self.function_definition_stack[-1].LBLine = b.start.line + self.function_definition_stack[-1].LBOffset = b.start.charPositionInLine + + + + + + retval.stop = self.input.LT(-1) + + if self.backtracking == 0: + + self.StoreFunctionDefinition(retval.start.line, retval.start.charPositionInLine, retval.stop.line, retval.stop.charPositionInLine, self.function_definition_stack[-1].ModifierText, self.function_definition_stack[-1].DeclText, self.function_definition_stack[-1].LBLine, self.function_definition_stack[-1].LBOffset, self.function_definition_stack[-1].DeclLine, self.function_definition_stack[-1].DeclOffset) + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 3, function_definition_StartIndex) + + self.function_definition_stack.pop() + pass + + return retval + + # $ANTLR end function_definition + + + # $ANTLR start declaration + # C.g:114:1: declaration : (a= 'typedef' (b= declaration_specifiers )? c= init_declarator_list d= ';' | s= declaration_specifiers (t= init_declarator_list )? e= ';' ); + def declaration(self, ): + + declaration_StartIndex = self.input.index() + a = None + d = None + e = None + b = None + + c = None + + s = None + + t = None + + + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 4): + return + + # C.g:115:2: (a= 'typedef' (b= declaration_specifiers )? c= init_declarator_list d= ';' | s= declaration_specifiers (t= init_declarator_list )? e= ';' ) + alt9 = 2 + LA9_0 = self.input.LA(1) + + if (LA9_0 == 26) : + alt9 = 1 + elif (LA9_0 == IDENTIFIER or (29 <= LA9_0 <= 42) or (45 <= LA9_0 <= 46) or (48 <= LA9_0 <= 60)) : + alt9 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("114:1: declaration : (a= 'typedef' (b= declaration_specifiers )? c= init_declarator_list d= ';' | s= declaration_specifiers (t= init_declarator_list )? e= ';' );", 9, 0, self.input) + + raise nvae + + if alt9 == 1: + # C.g:115:4: a= 'typedef' (b= declaration_specifiers )? c= init_declarator_list d= ';' + a = self.input.LT(1) + self.match(self.input, 26, self.FOLLOW_26_in_declaration193) + if self.failed: + return + # C.g:115:17: (b= declaration_specifiers )? + alt7 = 2 + LA7 = self.input.LA(1) + if LA7 == 29 or LA7 == 30 or LA7 == 31 or LA7 == 32 or LA7 == 33 or LA7 == 34 or LA7 == 35 or LA7 == 36 or LA7 == 37 or LA7 == 38 or LA7 == 39 or LA7 == 40 or LA7 == 41 or LA7 == 42 or LA7 == 45 or LA7 == 46 or LA7 == 48 or LA7 == 49 or LA7 == 50 or LA7 == 51 or LA7 == 52 or LA7 == 53 or LA7 == 54 or LA7 == 55 or LA7 == 56 or LA7 == 57: + alt7 = 1 + elif LA7 == IDENTIFIER: + LA7_13 = self.input.LA(2) + + if (LA7_13 == IDENTIFIER or (29 <= LA7_13 <= 42) or (45 <= LA7_13 <= 46) or (48 <= LA7_13 <= 60) or LA7_13 == 65) : + alt7 = 1 + elif (LA7_13 == 61) : + LA7_25 = self.input.LA(3) + + if (self.synpred10()) : + alt7 = 1 + elif LA7 == 58: + LA7_14 = self.input.LA(2) + + if (self.synpred10()) : + alt7 = 1 + elif LA7 == 59: + LA7_16 = self.input.LA(2) + + if (self.synpred10()) : + alt7 = 1 + elif LA7 == 60: + LA7_17 = self.input.LA(2) + + if (self.synpred10()) : + alt7 = 1 + if alt7 == 1: + # C.g:0:0: b= declaration_specifiers + self.following.append(self.FOLLOW_declaration_specifiers_in_declaration197) + b = self.declaration_specifiers() + self.following.pop() + if self.failed: + return + + + + self.following.append(self.FOLLOW_init_declarator_list_in_declaration206) + c = self.init_declarator_list() + self.following.pop() + if self.failed: + return + d = self.input.LT(1) + self.match(self.input, 25, self.FOLLOW_25_in_declaration210) + if self.failed: + return + if self.backtracking == 0: + + if b != None: + self.StoreTypedefDefinition(a.line, a.charPositionInLine, d.line, d.charPositionInLine, self.input.toString(b.start,b.stop), self.input.toString(c.start,c.stop)) + else: + self.StoreTypedefDefinition(a.line, a.charPositionInLine, d.line, d.charPositionInLine, '', self.input.toString(c.start,c.stop)) + + + + + elif alt9 == 2: + # C.g:123:4: s= declaration_specifiers (t= init_declarator_list )? e= ';' + self.following.append(self.FOLLOW_declaration_specifiers_in_declaration224) + s = self.declaration_specifiers() + self.following.pop() + if self.failed: + return + # C.g:123:30: (t= init_declarator_list )? + alt8 = 2 + LA8_0 = self.input.LA(1) + + if (LA8_0 == IDENTIFIER or (58 <= LA8_0 <= 61) or LA8_0 == 65) : + alt8 = 1 + if alt8 == 1: + # C.g:0:0: t= init_declarator_list + self.following.append(self.FOLLOW_init_declarator_list_in_declaration228) + t = self.init_declarator_list() + self.following.pop() + if self.failed: + return + + + + e = self.input.LT(1) + self.match(self.input, 25, self.FOLLOW_25_in_declaration233) + if self.failed: + return + if self.backtracking == 0: + + if t != None: + self.StoreVariableDeclaration(s.start.line, s.start.charPositionInLine, t.start.line, t.start.charPositionInLine, self.input.toString(s.start,s.stop), self.input.toString(t.start,t.stop)) + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 4, declaration_StartIndex) + + pass + + return + + # $ANTLR end declaration + + class declaration_specifiers_return(object): + def __init__(self): + self.start = None + self.stop = None + + + + # $ANTLR start declaration_specifiers + # C.g:130:1: declaration_specifiers : ( storage_class_specifier | type_specifier | type_qualifier )+ ; + def declaration_specifiers(self, ): + + retval = self.declaration_specifiers_return() + retval.start = self.input.LT(1) + declaration_specifiers_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 5): + return retval + + # C.g:131:2: ( ( storage_class_specifier | type_specifier | type_qualifier )+ ) + # C.g:131:6: ( storage_class_specifier | type_specifier | type_qualifier )+ + # C.g:131:6: ( storage_class_specifier | type_specifier | type_qualifier )+ + cnt10 = 0 + while True: #loop10 + alt10 = 4 + LA10 = self.input.LA(1) + if LA10 == 58: + LA10_2 = self.input.LA(2) + + if (self.synpred15()) : + alt10 = 3 + + + elif LA10 == 59: + LA10_3 = self.input.LA(2) + + if (self.synpred15()) : + alt10 = 3 + + + elif LA10 == 60: + LA10_4 = self.input.LA(2) + + if (self.synpred15()) : + alt10 = 3 + + + elif LA10 == IDENTIFIER: + LA10_5 = self.input.LA(2) + + if (self.synpred14()) : + alt10 = 2 + + + elif LA10 == 53: + LA10_9 = self.input.LA(2) + + if (self.synpred15()) : + alt10 = 3 + + + elif LA10 == 29 or LA10 == 30 or LA10 == 31 or LA10 == 32 or LA10 == 33: + alt10 = 1 + elif LA10 == 34 or LA10 == 35 or LA10 == 36 or LA10 == 37 or LA10 == 38 or LA10 == 39 or LA10 == 40 or LA10 == 41 or LA10 == 42 or LA10 == 45 or LA10 == 46 or LA10 == 48: + alt10 = 2 + elif LA10 == 49 or LA10 == 50 or LA10 == 51 or LA10 == 52 or LA10 == 54 or LA10 == 55 or LA10 == 56 or LA10 == 57: + alt10 = 3 + + if alt10 == 1: + # C.g:131:10: storage_class_specifier + self.following.append(self.FOLLOW_storage_class_specifier_in_declaration_specifiers254) + self.storage_class_specifier() + self.following.pop() + if self.failed: + return retval + + + elif alt10 == 2: + # C.g:132:7: type_specifier + self.following.append(self.FOLLOW_type_specifier_in_declaration_specifiers262) + self.type_specifier() + self.following.pop() + if self.failed: + return retval + + + elif alt10 == 3: + # C.g:133:13: type_qualifier + self.following.append(self.FOLLOW_type_qualifier_in_declaration_specifiers276) + self.type_qualifier() + self.following.pop() + if self.failed: + return retval + + + else: + if cnt10 >= 1: + break #loop10 + + if self.backtracking > 0: + self.failed = True + return retval + + eee = EarlyExitException(10, self.input) + raise eee + + cnt10 += 1 + + + + + + retval.stop = self.input.LT(-1) + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 5, declaration_specifiers_StartIndex) + + pass + + return retval + + # $ANTLR end declaration_specifiers + + class init_declarator_list_return(object): + def __init__(self): + self.start = None + self.stop = None + + + + # $ANTLR start init_declarator_list + # C.g:137:1: init_declarator_list : init_declarator ( ',' init_declarator )* ; + def init_declarator_list(self, ): + + retval = self.init_declarator_list_return() + retval.start = self.input.LT(1) + init_declarator_list_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 6): + return retval + + # C.g:138:2: ( init_declarator ( ',' init_declarator )* ) + # C.g:138:4: init_declarator ( ',' init_declarator )* + self.following.append(self.FOLLOW_init_declarator_in_init_declarator_list298) + self.init_declarator() + self.following.pop() + if self.failed: + return retval + # C.g:138:20: ( ',' init_declarator )* + while True: #loop11 + alt11 = 2 + LA11_0 = self.input.LA(1) + + if (LA11_0 == 27) : + alt11 = 1 + + + if alt11 == 1: + # C.g:138:21: ',' init_declarator + self.match(self.input, 27, self.FOLLOW_27_in_init_declarator_list301) + if self.failed: + return retval + self.following.append(self.FOLLOW_init_declarator_in_init_declarator_list303) + self.init_declarator() + self.following.pop() + if self.failed: + return retval + + + else: + break #loop11 + + + + + + retval.stop = self.input.LT(-1) + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 6, init_declarator_list_StartIndex) + + pass + + return retval + + # $ANTLR end init_declarator_list + + + # $ANTLR start init_declarator + # C.g:141:1: init_declarator : declarator ( '=' initializer )? ; + def init_declarator(self, ): + + init_declarator_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 7): + return + + # C.g:142:2: ( declarator ( '=' initializer )? ) + # C.g:142:4: declarator ( '=' initializer )? + self.following.append(self.FOLLOW_declarator_in_init_declarator316) + self.declarator() + self.following.pop() + if self.failed: + return + # C.g:142:15: ( '=' initializer )? + alt12 = 2 + LA12_0 = self.input.LA(1) + + if (LA12_0 == 28) : + alt12 = 1 + if alt12 == 1: + # C.g:142:16: '=' initializer + self.match(self.input, 28, self.FOLLOW_28_in_init_declarator319) + if self.failed: + return + self.following.append(self.FOLLOW_initializer_in_init_declarator321) + self.initializer() + self.following.pop() + if self.failed: + return + + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 7, init_declarator_StartIndex) + + pass + + return + + # $ANTLR end init_declarator + + + # $ANTLR start storage_class_specifier + # C.g:145:1: storage_class_specifier : ( 'extern' | 'static' | 'auto' | 'register' | 'STATIC' ); + def storage_class_specifier(self, ): + + storage_class_specifier_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 8): + return + + # C.g:146:2: ( 'extern' | 'static' | 'auto' | 'register' | 'STATIC' ) + # C.g: + if (29 <= self.input.LA(1) <= 33): + self.input.consume(); + self.errorRecovery = False + self.failed = False + + else: + if self.backtracking > 0: + self.failed = True + return + + mse = MismatchedSetException(None, self.input) + self.recoverFromMismatchedSet( + self.input, mse, self.FOLLOW_set_in_storage_class_specifier0 + ) + raise mse + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 8, storage_class_specifier_StartIndex) + + pass + + return + + # $ANTLR end storage_class_specifier + + + # $ANTLR start type_specifier + # C.g:153:1: type_specifier : ( 'void' | 'char' | 'short' | 'int' | 'long' | 'float' | 'double' | 'signed' | 'unsigned' | s= struct_or_union_specifier | e= enum_specifier | ( IDENTIFIER ( type_qualifier )* declarator )=> type_id ); + def type_specifier(self, ): + + type_specifier_StartIndex = self.input.index() + s = None + + e = None + + + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 9): + return + + # C.g:154:2: ( 'void' | 'char' | 'short' | 'int' | 'long' | 'float' | 'double' | 'signed' | 'unsigned' | s= struct_or_union_specifier | e= enum_specifier | ( IDENTIFIER ( type_qualifier )* declarator )=> type_id ) + alt13 = 12 + LA13_0 = self.input.LA(1) + + if (LA13_0 == 34) : + alt13 = 1 + elif (LA13_0 == 35) : + alt13 = 2 + elif (LA13_0 == 36) : + alt13 = 3 + elif (LA13_0 == 37) : + alt13 = 4 + elif (LA13_0 == 38) : + alt13 = 5 + elif (LA13_0 == 39) : + alt13 = 6 + elif (LA13_0 == 40) : + alt13 = 7 + elif (LA13_0 == 41) : + alt13 = 8 + elif (LA13_0 == 42) : + alt13 = 9 + elif ((45 <= LA13_0 <= 46)) : + alt13 = 10 + elif (LA13_0 == 48) : + alt13 = 11 + elif (LA13_0 == IDENTIFIER) and (self.synpred34()): + alt13 = 12 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("153:1: type_specifier : ( 'void' | 'char' | 'short' | 'int' | 'long' | 'float' | 'double' | 'signed' | 'unsigned' | s= struct_or_union_specifier | e= enum_specifier | ( IDENTIFIER ( type_qualifier )* declarator )=> type_id );", 13, 0, self.input) + + raise nvae + + if alt13 == 1: + # C.g:154:4: 'void' + self.match(self.input, 34, self.FOLLOW_34_in_type_specifier366) + if self.failed: + return + + + elif alt13 == 2: + # C.g:155:4: 'char' + self.match(self.input, 35, self.FOLLOW_35_in_type_specifier371) + if self.failed: + return + + + elif alt13 == 3: + # C.g:156:4: 'short' + self.match(self.input, 36, self.FOLLOW_36_in_type_specifier376) + if self.failed: + return + + + elif alt13 == 4: + # C.g:157:4: 'int' + self.match(self.input, 37, self.FOLLOW_37_in_type_specifier381) + if self.failed: + return + + + elif alt13 == 5: + # C.g:158:4: 'long' + self.match(self.input, 38, self.FOLLOW_38_in_type_specifier386) + if self.failed: + return + + + elif alt13 == 6: + # C.g:159:4: 'float' + self.match(self.input, 39, self.FOLLOW_39_in_type_specifier391) + if self.failed: + return + + + elif alt13 == 7: + # C.g:160:4: 'double' + self.match(self.input, 40, self.FOLLOW_40_in_type_specifier396) + if self.failed: + return + + + elif alt13 == 8: + # C.g:161:4: 'signed' + self.match(self.input, 41, self.FOLLOW_41_in_type_specifier401) + if self.failed: + return + + + elif alt13 == 9: + # C.g:162:4: 'unsigned' + self.match(self.input, 42, self.FOLLOW_42_in_type_specifier406) + if self.failed: + return + + + elif alt13 == 10: + # C.g:163:4: s= struct_or_union_specifier + self.following.append(self.FOLLOW_struct_or_union_specifier_in_type_specifier413) + s = self.struct_or_union_specifier() + self.following.pop() + if self.failed: + return + if self.backtracking == 0: + + if s.stop != None: + self.StoreStructUnionDefinition(s.start.line, s.start.charPositionInLine, s.stop.line, s.stop.charPositionInLine, self.input.toString(s.start,s.stop)) + + + + + elif alt13 == 11: + # C.g:168:4: e= enum_specifier + self.following.append(self.FOLLOW_enum_specifier_in_type_specifier423) + e = self.enum_specifier() + self.following.pop() + if self.failed: + return + if self.backtracking == 0: + + if e.stop != None: + self.StoreEnumerationDefinition(e.start.line, e.start.charPositionInLine, e.stop.line, e.stop.charPositionInLine, self.input.toString(e.start,e.stop)) + + + + + elif alt13 == 12: + # C.g:173:4: ( IDENTIFIER ( type_qualifier )* declarator )=> type_id + self.following.append(self.FOLLOW_type_id_in_type_specifier441) + self.type_id() + self.following.pop() + if self.failed: + return + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 9, type_specifier_StartIndex) + + pass + + return + + # $ANTLR end type_specifier + + + # $ANTLR start type_id + # C.g:176:1: type_id : IDENTIFIER ; + def type_id(self, ): + + type_id_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 10): + return + + # C.g:177:5: ( IDENTIFIER ) + # C.g:177:9: IDENTIFIER + self.match(self.input, IDENTIFIER, self.FOLLOW_IDENTIFIER_in_type_id457) + if self.failed: + return + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 10, type_id_StartIndex) + + pass + + return + + # $ANTLR end type_id + + class struct_or_union_specifier_return(object): + def __init__(self): + self.start = None + self.stop = None + + + + # $ANTLR start struct_or_union_specifier + # C.g:181:1: struct_or_union_specifier options {k=3; } : ( struct_or_union ( IDENTIFIER )? '{' struct_declaration_list '}' | struct_or_union IDENTIFIER ); + def struct_or_union_specifier(self, ): + + retval = self.struct_or_union_specifier_return() + retval.start = self.input.LT(1) + struct_or_union_specifier_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 11): + return retval + + # C.g:183:2: ( struct_or_union ( IDENTIFIER )? '{' struct_declaration_list '}' | struct_or_union IDENTIFIER ) + alt15 = 2 + LA15_0 = self.input.LA(1) + + if ((45 <= LA15_0 <= 46)) : + LA15_1 = self.input.LA(2) + + if (LA15_1 == IDENTIFIER) : + LA15_2 = self.input.LA(3) + + if (LA15_2 == 43) : + alt15 = 1 + elif (LA15_2 == EOF or LA15_2 == IDENTIFIER or LA15_2 == 25 or LA15_2 == 27 or (29 <= LA15_2 <= 42) or (45 <= LA15_2 <= 63) or LA15_2 == 65) : + alt15 = 2 + else: + if self.backtracking > 0: + self.failed = True + return retval + + nvae = NoViableAltException("181:1: struct_or_union_specifier options {k=3; } : ( struct_or_union ( IDENTIFIER )? '{' struct_declaration_list '}' | struct_or_union IDENTIFIER );", 15, 2, self.input) + + raise nvae + + elif (LA15_1 == 43) : + alt15 = 1 + else: + if self.backtracking > 0: + self.failed = True + return retval + + nvae = NoViableAltException("181:1: struct_or_union_specifier options {k=3; } : ( struct_or_union ( IDENTIFIER )? '{' struct_declaration_list '}' | struct_or_union IDENTIFIER );", 15, 1, self.input) + + raise nvae + + else: + if self.backtracking > 0: + self.failed = True + return retval + + nvae = NoViableAltException("181:1: struct_or_union_specifier options {k=3; } : ( struct_or_union ( IDENTIFIER )? '{' struct_declaration_list '}' | struct_or_union IDENTIFIER );", 15, 0, self.input) + + raise nvae + + if alt15 == 1: + # C.g:183:4: struct_or_union ( IDENTIFIER )? '{' struct_declaration_list '}' + self.following.append(self.FOLLOW_struct_or_union_in_struct_or_union_specifier484) + self.struct_or_union() + self.following.pop() + if self.failed: + return retval + # C.g:183:20: ( IDENTIFIER )? + alt14 = 2 + LA14_0 = self.input.LA(1) + + if (LA14_0 == IDENTIFIER) : + alt14 = 1 + if alt14 == 1: + # C.g:0:0: IDENTIFIER + self.match(self.input, IDENTIFIER, self.FOLLOW_IDENTIFIER_in_struct_or_union_specifier486) + if self.failed: + return retval + + + + self.match(self.input, 43, self.FOLLOW_43_in_struct_or_union_specifier489) + if self.failed: + return retval + self.following.append(self.FOLLOW_struct_declaration_list_in_struct_or_union_specifier491) + self.struct_declaration_list() + self.following.pop() + if self.failed: + return retval + self.match(self.input, 44, self.FOLLOW_44_in_struct_or_union_specifier493) + if self.failed: + return retval + + + elif alt15 == 2: + # C.g:184:4: struct_or_union IDENTIFIER + self.following.append(self.FOLLOW_struct_or_union_in_struct_or_union_specifier498) + self.struct_or_union() + self.following.pop() + if self.failed: + return retval + self.match(self.input, IDENTIFIER, self.FOLLOW_IDENTIFIER_in_struct_or_union_specifier500) + if self.failed: + return retval + + + retval.stop = self.input.LT(-1) + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 11, struct_or_union_specifier_StartIndex) + + pass + + return retval + + # $ANTLR end struct_or_union_specifier + + + # $ANTLR start struct_or_union + # C.g:187:1: struct_or_union : ( 'struct' | 'union' ); + def struct_or_union(self, ): + + struct_or_union_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 12): + return + + # C.g:188:2: ( 'struct' | 'union' ) + # C.g: + if (45 <= self.input.LA(1) <= 46): + self.input.consume(); + self.errorRecovery = False + self.failed = False + + else: + if self.backtracking > 0: + self.failed = True + return + + mse = MismatchedSetException(None, self.input) + self.recoverFromMismatchedSet( + self.input, mse, self.FOLLOW_set_in_struct_or_union0 + ) + raise mse + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 12, struct_or_union_StartIndex) + + pass + + return + + # $ANTLR end struct_or_union + + + # $ANTLR start struct_declaration_list + # C.g:192:1: struct_declaration_list : ( struct_declaration )+ ; + def struct_declaration_list(self, ): + + struct_declaration_list_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 13): + return + + # C.g:193:2: ( ( struct_declaration )+ ) + # C.g:193:4: ( struct_declaration )+ + # C.g:193:4: ( struct_declaration )+ + cnt16 = 0 + while True: #loop16 + alt16 = 2 + LA16_0 = self.input.LA(1) + + if (LA16_0 == IDENTIFIER or (34 <= LA16_0 <= 42) or (45 <= LA16_0 <= 46) or (48 <= LA16_0 <= 60)) : + alt16 = 1 + + + if alt16 == 1: + # C.g:0:0: struct_declaration + self.following.append(self.FOLLOW_struct_declaration_in_struct_declaration_list527) + self.struct_declaration() + self.following.pop() + if self.failed: + return + + + else: + if cnt16 >= 1: + break #loop16 + + if self.backtracking > 0: + self.failed = True + return + + eee = EarlyExitException(16, self.input) + raise eee + + cnt16 += 1 + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 13, struct_declaration_list_StartIndex) + + pass + + return + + # $ANTLR end struct_declaration_list + + + # $ANTLR start struct_declaration + # C.g:196:1: struct_declaration : specifier_qualifier_list struct_declarator_list ';' ; + def struct_declaration(self, ): + + struct_declaration_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 14): + return + + # C.g:197:2: ( specifier_qualifier_list struct_declarator_list ';' ) + # C.g:197:4: specifier_qualifier_list struct_declarator_list ';' + self.following.append(self.FOLLOW_specifier_qualifier_list_in_struct_declaration539) + self.specifier_qualifier_list() + self.following.pop() + if self.failed: + return + self.following.append(self.FOLLOW_struct_declarator_list_in_struct_declaration541) + self.struct_declarator_list() + self.following.pop() + if self.failed: + return + self.match(self.input, 25, self.FOLLOW_25_in_struct_declaration543) + if self.failed: + return + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 14, struct_declaration_StartIndex) + + pass + + return + + # $ANTLR end struct_declaration + + + # $ANTLR start specifier_qualifier_list + # C.g:200:1: specifier_qualifier_list : ( type_qualifier | type_specifier )+ ; + def specifier_qualifier_list(self, ): + + specifier_qualifier_list_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 15): + return + + # C.g:201:2: ( ( type_qualifier | type_specifier )+ ) + # C.g:201:4: ( type_qualifier | type_specifier )+ + # C.g:201:4: ( type_qualifier | type_specifier )+ + cnt17 = 0 + while True: #loop17 + alt17 = 3 + LA17 = self.input.LA(1) + if LA17 == 58: + LA17_2 = self.input.LA(2) + + if (self.synpred39()) : + alt17 = 1 + + + elif LA17 == 59: + LA17_3 = self.input.LA(2) + + if (self.synpred39()) : + alt17 = 1 + + + elif LA17 == 60: + LA17_4 = self.input.LA(2) + + if (self.synpred39()) : + alt17 = 1 + + + elif LA17 == IDENTIFIER: + LA17 = self.input.LA(2) + if LA17 == EOF or LA17 == IDENTIFIER or LA17 == 34 or LA17 == 35 or LA17 == 36 or LA17 == 37 or LA17 == 38 or LA17 == 39 or LA17 == 40 or LA17 == 41 or LA17 == 42 or LA17 == 45 or LA17 == 46 or LA17 == 48 or LA17 == 49 or LA17 == 50 or LA17 == 51 or LA17 == 52 or LA17 == 53 or LA17 == 54 or LA17 == 55 or LA17 == 56 or LA17 == 57 or LA17 == 58 or LA17 == 59 or LA17 == 60 or LA17 == 62 or LA17 == 65: + alt17 = 2 + elif LA17 == 61: + LA17_94 = self.input.LA(3) + + if (self.synpred40()) : + alt17 = 2 + + + elif LA17 == 47: + LA17_95 = self.input.LA(3) + + if (self.synpred40()) : + alt17 = 2 + + + elif LA17 == 63: + LA17_96 = self.input.LA(3) + + if (self.synpred40()) : + alt17 = 2 + + + + elif LA17 == 49 or LA17 == 50 or LA17 == 51 or LA17 == 52 or LA17 == 53 or LA17 == 54 or LA17 == 55 or LA17 == 56 or LA17 == 57: + alt17 = 1 + elif LA17 == 34 or LA17 == 35 or LA17 == 36 or LA17 == 37 or LA17 == 38 or LA17 == 39 or LA17 == 40 or LA17 == 41 or LA17 == 42 or LA17 == 45 or LA17 == 46 or LA17 == 48: + alt17 = 2 + + if alt17 == 1: + # C.g:201:6: type_qualifier + self.following.append(self.FOLLOW_type_qualifier_in_specifier_qualifier_list556) + self.type_qualifier() + self.following.pop() + if self.failed: + return + + + elif alt17 == 2: + # C.g:201:23: type_specifier + self.following.append(self.FOLLOW_type_specifier_in_specifier_qualifier_list560) + self.type_specifier() + self.following.pop() + if self.failed: + return + + + else: + if cnt17 >= 1: + break #loop17 + + if self.backtracking > 0: + self.failed = True + return + + eee = EarlyExitException(17, self.input) + raise eee + + cnt17 += 1 + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 15, specifier_qualifier_list_StartIndex) + + pass + + return + + # $ANTLR end specifier_qualifier_list + + + # $ANTLR start struct_declarator_list + # C.g:204:1: struct_declarator_list : struct_declarator ( ',' struct_declarator )* ; + def struct_declarator_list(self, ): + + struct_declarator_list_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 16): + return + + # C.g:205:2: ( struct_declarator ( ',' struct_declarator )* ) + # C.g:205:4: struct_declarator ( ',' struct_declarator )* + self.following.append(self.FOLLOW_struct_declarator_in_struct_declarator_list574) + self.struct_declarator() + self.following.pop() + if self.failed: + return + # C.g:205:22: ( ',' struct_declarator )* + while True: #loop18 + alt18 = 2 + LA18_0 = self.input.LA(1) + + if (LA18_0 == 27) : + alt18 = 1 + + + if alt18 == 1: + # C.g:205:23: ',' struct_declarator + self.match(self.input, 27, self.FOLLOW_27_in_struct_declarator_list577) + if self.failed: + return + self.following.append(self.FOLLOW_struct_declarator_in_struct_declarator_list579) + self.struct_declarator() + self.following.pop() + if self.failed: + return + + + else: + break #loop18 + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 16, struct_declarator_list_StartIndex) + + pass + + return + + # $ANTLR end struct_declarator_list + + + # $ANTLR start struct_declarator + # C.g:208:1: struct_declarator : ( declarator ( ':' constant_expression )? | ':' constant_expression ); + def struct_declarator(self, ): + + struct_declarator_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 17): + return + + # C.g:209:2: ( declarator ( ':' constant_expression )? | ':' constant_expression ) + alt20 = 2 + LA20_0 = self.input.LA(1) + + if (LA20_0 == IDENTIFIER or (58 <= LA20_0 <= 61) or LA20_0 == 65) : + alt20 = 1 + elif (LA20_0 == 47) : + alt20 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("208:1: struct_declarator : ( declarator ( ':' constant_expression )? | ':' constant_expression );", 20, 0, self.input) + + raise nvae + + if alt20 == 1: + # C.g:209:4: declarator ( ':' constant_expression )? + self.following.append(self.FOLLOW_declarator_in_struct_declarator592) + self.declarator() + self.following.pop() + if self.failed: + return + # C.g:209:15: ( ':' constant_expression )? + alt19 = 2 + LA19_0 = self.input.LA(1) + + if (LA19_0 == 47) : + alt19 = 1 + if alt19 == 1: + # C.g:209:16: ':' constant_expression + self.match(self.input, 47, self.FOLLOW_47_in_struct_declarator595) + if self.failed: + return + self.following.append(self.FOLLOW_constant_expression_in_struct_declarator597) + self.constant_expression() + self.following.pop() + if self.failed: + return + + + + + + elif alt20 == 2: + # C.g:210:4: ':' constant_expression + self.match(self.input, 47, self.FOLLOW_47_in_struct_declarator604) + if self.failed: + return + self.following.append(self.FOLLOW_constant_expression_in_struct_declarator606) + self.constant_expression() + self.following.pop() + if self.failed: + return + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 17, struct_declarator_StartIndex) + + pass + + return + + # $ANTLR end struct_declarator + + class enum_specifier_return(object): + def __init__(self): + self.start = None + self.stop = None + + + + # $ANTLR start enum_specifier + # C.g:213:1: enum_specifier options {k=3; } : ( 'enum' '{' enumerator_list ( ',' )? '}' | 'enum' IDENTIFIER '{' enumerator_list ( ',' )? '}' | 'enum' IDENTIFIER ); + def enum_specifier(self, ): + + retval = self.enum_specifier_return() + retval.start = self.input.LT(1) + enum_specifier_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 18): + return retval + + # C.g:215:2: ( 'enum' '{' enumerator_list ( ',' )? '}' | 'enum' IDENTIFIER '{' enumerator_list ( ',' )? '}' | 'enum' IDENTIFIER ) + alt23 = 3 + LA23_0 = self.input.LA(1) + + if (LA23_0 == 48) : + LA23_1 = self.input.LA(2) + + if (LA23_1 == IDENTIFIER) : + LA23_2 = self.input.LA(3) + + if (LA23_2 == 43) : + alt23 = 2 + elif (LA23_2 == EOF or LA23_2 == IDENTIFIER or LA23_2 == 25 or LA23_2 == 27 or (29 <= LA23_2 <= 42) or (45 <= LA23_2 <= 63) or LA23_2 == 65) : + alt23 = 3 + else: + if self.backtracking > 0: + self.failed = True + return retval + + nvae = NoViableAltException("213:1: enum_specifier options {k=3; } : ( 'enum' '{' enumerator_list ( ',' )? '}' | 'enum' IDENTIFIER '{' enumerator_list ( ',' )? '}' | 'enum' IDENTIFIER );", 23, 2, self.input) + + raise nvae + + elif (LA23_1 == 43) : + alt23 = 1 + else: + if self.backtracking > 0: + self.failed = True + return retval + + nvae = NoViableAltException("213:1: enum_specifier options {k=3; } : ( 'enum' '{' enumerator_list ( ',' )? '}' | 'enum' IDENTIFIER '{' enumerator_list ( ',' )? '}' | 'enum' IDENTIFIER );", 23, 1, self.input) + + raise nvae + + else: + if self.backtracking > 0: + self.failed = True + return retval + + nvae = NoViableAltException("213:1: enum_specifier options {k=3; } : ( 'enum' '{' enumerator_list ( ',' )? '}' | 'enum' IDENTIFIER '{' enumerator_list ( ',' )? '}' | 'enum' IDENTIFIER );", 23, 0, self.input) + + raise nvae + + if alt23 == 1: + # C.g:215:4: 'enum' '{' enumerator_list ( ',' )? '}' + self.match(self.input, 48, self.FOLLOW_48_in_enum_specifier624) + if self.failed: + return retval + self.match(self.input, 43, self.FOLLOW_43_in_enum_specifier626) + if self.failed: + return retval + self.following.append(self.FOLLOW_enumerator_list_in_enum_specifier628) + self.enumerator_list() + self.following.pop() + if self.failed: + return retval + # C.g:215:31: ( ',' )? + alt21 = 2 + LA21_0 = self.input.LA(1) + + if (LA21_0 == 27) : + alt21 = 1 + if alt21 == 1: + # C.g:0:0: ',' + self.match(self.input, 27, self.FOLLOW_27_in_enum_specifier630) + if self.failed: + return retval + + + + self.match(self.input, 44, self.FOLLOW_44_in_enum_specifier633) + if self.failed: + return retval + + + elif alt23 == 2: + # C.g:216:4: 'enum' IDENTIFIER '{' enumerator_list ( ',' )? '}' + self.match(self.input, 48, self.FOLLOW_48_in_enum_specifier638) + if self.failed: + return retval + self.match(self.input, IDENTIFIER, self.FOLLOW_IDENTIFIER_in_enum_specifier640) + if self.failed: + return retval + self.match(self.input, 43, self.FOLLOW_43_in_enum_specifier642) + if self.failed: + return retval + self.following.append(self.FOLLOW_enumerator_list_in_enum_specifier644) + self.enumerator_list() + self.following.pop() + if self.failed: + return retval + # C.g:216:42: ( ',' )? + alt22 = 2 + LA22_0 = self.input.LA(1) + + if (LA22_0 == 27) : + alt22 = 1 + if alt22 == 1: + # C.g:0:0: ',' + self.match(self.input, 27, self.FOLLOW_27_in_enum_specifier646) + if self.failed: + return retval + + + + self.match(self.input, 44, self.FOLLOW_44_in_enum_specifier649) + if self.failed: + return retval + + + elif alt23 == 3: + # C.g:217:4: 'enum' IDENTIFIER + self.match(self.input, 48, self.FOLLOW_48_in_enum_specifier654) + if self.failed: + return retval + self.match(self.input, IDENTIFIER, self.FOLLOW_IDENTIFIER_in_enum_specifier656) + if self.failed: + return retval + + + retval.stop = self.input.LT(-1) + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 18, enum_specifier_StartIndex) + + pass + + return retval + + # $ANTLR end enum_specifier + + + # $ANTLR start enumerator_list + # C.g:220:1: enumerator_list : enumerator ( ',' enumerator )* ; + def enumerator_list(self, ): + + enumerator_list_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 19): + return + + # C.g:221:2: ( enumerator ( ',' enumerator )* ) + # C.g:221:4: enumerator ( ',' enumerator )* + self.following.append(self.FOLLOW_enumerator_in_enumerator_list667) + self.enumerator() + self.following.pop() + if self.failed: + return + # C.g:221:15: ( ',' enumerator )* + while True: #loop24 + alt24 = 2 + LA24_0 = self.input.LA(1) + + if (LA24_0 == 27) : + LA24_1 = self.input.LA(2) + + if (LA24_1 == IDENTIFIER) : + alt24 = 1 + + + + + if alt24 == 1: + # C.g:221:16: ',' enumerator + self.match(self.input, 27, self.FOLLOW_27_in_enumerator_list670) + if self.failed: + return + self.following.append(self.FOLLOW_enumerator_in_enumerator_list672) + self.enumerator() + self.following.pop() + if self.failed: + return + + + else: + break #loop24 + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 19, enumerator_list_StartIndex) + + pass + + return + + # $ANTLR end enumerator_list + + + # $ANTLR start enumerator + # C.g:224:1: enumerator : IDENTIFIER ( '=' constant_expression )? ; + def enumerator(self, ): + + enumerator_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 20): + return + + # C.g:225:2: ( IDENTIFIER ( '=' constant_expression )? ) + # C.g:225:4: IDENTIFIER ( '=' constant_expression )? + self.match(self.input, IDENTIFIER, self.FOLLOW_IDENTIFIER_in_enumerator685) + if self.failed: + return + # C.g:225:15: ( '=' constant_expression )? + alt25 = 2 + LA25_0 = self.input.LA(1) + + if (LA25_0 == 28) : + alt25 = 1 + if alt25 == 1: + # C.g:225:16: '=' constant_expression + self.match(self.input, 28, self.FOLLOW_28_in_enumerator688) + if self.failed: + return + self.following.append(self.FOLLOW_constant_expression_in_enumerator690) + self.constant_expression() + self.following.pop() + if self.failed: + return + + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 20, enumerator_StartIndex) + + pass + + return + + # $ANTLR end enumerator + + + # $ANTLR start type_qualifier + # C.g:228:1: type_qualifier : ( 'const' | 'volatile' | 'IN' | 'OUT' | 'OPTIONAL' | 'CONST' | 'UNALIGNED' | 'VOLATILE' | 'GLOBAL_REMOVE_IF_UNREFERENCED' | 'EFIAPI' | 'EFI_BOOTSERVICE' | 'EFI_RUNTIMESERVICE' ); + def type_qualifier(self, ): + + type_qualifier_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 21): + return + + # C.g:229:2: ( 'const' | 'volatile' | 'IN' | 'OUT' | 'OPTIONAL' | 'CONST' | 'UNALIGNED' | 'VOLATILE' | 'GLOBAL_REMOVE_IF_UNREFERENCED' | 'EFIAPI' | 'EFI_BOOTSERVICE' | 'EFI_RUNTIMESERVICE' ) + # C.g: + if (49 <= self.input.LA(1) <= 60): + self.input.consume(); + self.errorRecovery = False + self.failed = False + + else: + if self.backtracking > 0: + self.failed = True + return + + mse = MismatchedSetException(None, self.input) + self.recoverFromMismatchedSet( + self.input, mse, self.FOLLOW_set_in_type_qualifier0 + ) + raise mse + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 21, type_qualifier_StartIndex) + + pass + + return + + # $ANTLR end type_qualifier + + class declarator_return(object): + def __init__(self): + self.start = None + self.stop = None + + + + # $ANTLR start declarator + # C.g:243:1: declarator : ( ( pointer )? ( 'EFIAPI' )? ( 'EFI_BOOTSERVICE' )? ( 'EFI_RUNTIMESERVICE' )? direct_declarator | pointer ); + def declarator(self, ): + + retval = self.declarator_return() + retval.start = self.input.LT(1) + declarator_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 22): + return retval + + # C.g:244:2: ( ( pointer )? ( 'EFIAPI' )? ( 'EFI_BOOTSERVICE' )? ( 'EFI_RUNTIMESERVICE' )? direct_declarator | pointer ) + alt30 = 2 + LA30_0 = self.input.LA(1) + + if (LA30_0 == 65) : + LA30_1 = self.input.LA(2) + + if (self.synpred65()) : + alt30 = 1 + elif (True) : + alt30 = 2 + else: + if self.backtracking > 0: + self.failed = True + return retval + + nvae = NoViableAltException("243:1: declarator : ( ( pointer )? ( 'EFIAPI' )? ( 'EFI_BOOTSERVICE' )? ( 'EFI_RUNTIMESERVICE' )? direct_declarator | pointer );", 30, 1, self.input) + + raise nvae + + elif (LA30_0 == IDENTIFIER or (58 <= LA30_0 <= 61)) : + alt30 = 1 + else: + if self.backtracking > 0: + self.failed = True + return retval + + nvae = NoViableAltException("243:1: declarator : ( ( pointer )? ( 'EFIAPI' )? ( 'EFI_BOOTSERVICE' )? ( 'EFI_RUNTIMESERVICE' )? direct_declarator | pointer );", 30, 0, self.input) + + raise nvae + + if alt30 == 1: + # C.g:244:4: ( pointer )? ( 'EFIAPI' )? ( 'EFI_BOOTSERVICE' )? ( 'EFI_RUNTIMESERVICE' )? direct_declarator + # C.g:244:4: ( pointer )? + alt26 = 2 + LA26_0 = self.input.LA(1) + + if (LA26_0 == 65) : + alt26 = 1 + if alt26 == 1: + # C.g:0:0: pointer + self.following.append(self.FOLLOW_pointer_in_declarator769) + self.pointer() + self.following.pop() + if self.failed: + return retval + + + + # C.g:244:13: ( 'EFIAPI' )? + alt27 = 2 + LA27_0 = self.input.LA(1) + + if (LA27_0 == 58) : + alt27 = 1 + if alt27 == 1: + # C.g:244:14: 'EFIAPI' + self.match(self.input, 58, self.FOLLOW_58_in_declarator773) + if self.failed: + return retval + + + + # C.g:244:25: ( 'EFI_BOOTSERVICE' )? + alt28 = 2 + LA28_0 = self.input.LA(1) + + if (LA28_0 == 59) : + alt28 = 1 + if alt28 == 1: + # C.g:244:26: 'EFI_BOOTSERVICE' + self.match(self.input, 59, self.FOLLOW_59_in_declarator778) + if self.failed: + return retval + + + + # C.g:244:46: ( 'EFI_RUNTIMESERVICE' )? + alt29 = 2 + LA29_0 = self.input.LA(1) + + if (LA29_0 == 60) : + alt29 = 1 + if alt29 == 1: + # C.g:244:47: 'EFI_RUNTIMESERVICE' + self.match(self.input, 60, self.FOLLOW_60_in_declarator783) + if self.failed: + return retval + + + + self.following.append(self.FOLLOW_direct_declarator_in_declarator787) + self.direct_declarator() + self.following.pop() + if self.failed: + return retval + + + elif alt30 == 2: + # C.g:246:4: pointer + self.following.append(self.FOLLOW_pointer_in_declarator793) + self.pointer() + self.following.pop() + if self.failed: + return retval + + + retval.stop = self.input.LT(-1) + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 22, declarator_StartIndex) + + pass + + return retval + + # $ANTLR end declarator + + + # $ANTLR start direct_declarator + # C.g:249:1: direct_declarator : ( IDENTIFIER ( declarator_suffix )* | '(' ( 'EFIAPI' )? declarator ')' ( declarator_suffix )+ ); + def direct_declarator(self, ): + + direct_declarator_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 23): + return + + # C.g:250:2: ( IDENTIFIER ( declarator_suffix )* | '(' ( 'EFIAPI' )? declarator ')' ( declarator_suffix )+ ) + alt34 = 2 + LA34_0 = self.input.LA(1) + + if (LA34_0 == IDENTIFIER) : + alt34 = 1 + elif (LA34_0 == 61) : + alt34 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("249:1: direct_declarator : ( IDENTIFIER ( declarator_suffix )* | '(' ( 'EFIAPI' )? declarator ')' ( declarator_suffix )+ );", 34, 0, self.input) + + raise nvae + + if alt34 == 1: + # C.g:250:4: IDENTIFIER ( declarator_suffix )* + self.match(self.input, IDENTIFIER, self.FOLLOW_IDENTIFIER_in_direct_declarator804) + if self.failed: + return + # C.g:250:15: ( declarator_suffix )* + while True: #loop31 + alt31 = 2 + LA31_0 = self.input.LA(1) + + if (LA31_0 == 61) : + LA31 = self.input.LA(2) + if LA31 == 62: + LA31_30 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == 58: + LA31_31 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == 65: + LA31_32 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == 59: + LA31_33 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == 60: + LA31_34 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == IDENTIFIER: + LA31_35 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == 29 or LA31 == 30 or LA31 == 31 or LA31 == 32 or LA31 == 33: + LA31_37 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == 34: + LA31_38 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == 35: + LA31_39 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == 36: + LA31_40 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == 37: + LA31_41 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == 38: + LA31_42 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == 39: + LA31_43 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == 40: + LA31_44 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == 41: + LA31_45 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == 42: + LA31_46 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == 45 or LA31 == 46: + LA31_47 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == 48: + LA31_48 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == 49 or LA31 == 50 or LA31 == 51 or LA31 == 52 or LA31 == 53 or LA31 == 54 or LA31 == 55 or LA31 == 56 or LA31 == 57: + LA31_49 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + + elif (LA31_0 == 63) : + LA31 = self.input.LA(2) + if LA31 == 64: + LA31_51 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == 61: + LA31_52 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == IDENTIFIER: + LA31_53 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == HEX_LITERAL: + LA31_54 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == OCTAL_LITERAL: + LA31_55 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == DECIMAL_LITERAL: + LA31_56 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == CHARACTER_LITERAL: + LA31_57 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == STRING_LITERAL: + LA31_58 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == FLOATING_POINT_LITERAL: + LA31_59 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == 71: + LA31_60 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == 72: + LA31_61 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == 65 or LA31 == 67 or LA31 == 68 or LA31 == 76 or LA31 == 77 or LA31 == 78: + LA31_62 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + elif LA31 == 73: + LA31_63 = self.input.LA(3) + + if (self.synpred66()) : + alt31 = 1 + + + + + + if alt31 == 1: + # C.g:0:0: declarator_suffix + self.following.append(self.FOLLOW_declarator_suffix_in_direct_declarator806) + self.declarator_suffix() + self.following.pop() + if self.failed: + return + + + else: + break #loop31 + + + + + elif alt34 == 2: + # C.g:251:4: '(' ( 'EFIAPI' )? declarator ')' ( declarator_suffix )+ + self.match(self.input, 61, self.FOLLOW_61_in_direct_declarator812) + if self.failed: + return + # C.g:251:8: ( 'EFIAPI' )? + alt32 = 2 + LA32_0 = self.input.LA(1) + + if (LA32_0 == 58) : + LA32_1 = self.input.LA(2) + + if (self.synpred68()) : + alt32 = 1 + if alt32 == 1: + # C.g:251:9: 'EFIAPI' + self.match(self.input, 58, self.FOLLOW_58_in_direct_declarator815) + if self.failed: + return + + + + self.following.append(self.FOLLOW_declarator_in_direct_declarator819) + self.declarator() + self.following.pop() + if self.failed: + return + self.match(self.input, 62, self.FOLLOW_62_in_direct_declarator821) + if self.failed: + return + # C.g:251:35: ( declarator_suffix )+ + cnt33 = 0 + while True: #loop33 + alt33 = 2 + LA33_0 = self.input.LA(1) + + if (LA33_0 == 61) : + LA33 = self.input.LA(2) + if LA33 == 62: + LA33_30 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == 58: + LA33_31 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == 65: + LA33_32 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == 59: + LA33_33 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == 60: + LA33_34 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == IDENTIFIER: + LA33_35 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == 29 or LA33 == 30 or LA33 == 31 or LA33 == 32 or LA33 == 33: + LA33_37 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == 34: + LA33_38 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == 35: + LA33_39 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == 36: + LA33_40 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == 37: + LA33_41 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == 38: + LA33_42 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == 39: + LA33_43 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == 40: + LA33_44 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == 41: + LA33_45 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == 42: + LA33_46 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == 45 or LA33 == 46: + LA33_47 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == 48: + LA33_48 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == 49 or LA33 == 50 or LA33 == 51 or LA33 == 52 or LA33 == 53 or LA33 == 54 or LA33 == 55 or LA33 == 56 or LA33 == 57: + LA33_49 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + + elif (LA33_0 == 63) : + LA33 = self.input.LA(2) + if LA33 == 64: + LA33_51 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == 61: + LA33_52 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == IDENTIFIER: + LA33_53 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == HEX_LITERAL: + LA33_54 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == OCTAL_LITERAL: + LA33_55 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == DECIMAL_LITERAL: + LA33_56 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == CHARACTER_LITERAL: + LA33_57 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == STRING_LITERAL: + LA33_58 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == FLOATING_POINT_LITERAL: + LA33_59 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == 71: + LA33_60 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == 72: + LA33_61 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == 65 or LA33 == 67 or LA33 == 68 or LA33 == 76 or LA33 == 77 or LA33 == 78: + LA33_62 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + elif LA33 == 73: + LA33_63 = self.input.LA(3) + + if (self.synpred69()) : + alt33 = 1 + + + + + + if alt33 == 1: + # C.g:0:0: declarator_suffix + self.following.append(self.FOLLOW_declarator_suffix_in_direct_declarator823) + self.declarator_suffix() + self.following.pop() + if self.failed: + return + + + else: + if cnt33 >= 1: + break #loop33 + + if self.backtracking > 0: + self.failed = True + return + + eee = EarlyExitException(33, self.input) + raise eee + + cnt33 += 1 + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 23, direct_declarator_StartIndex) + + pass + + return + + # $ANTLR end direct_declarator + + + # $ANTLR start declarator_suffix + # C.g:254:1: declarator_suffix : ( '[' constant_expression ']' | '[' ']' | '(' parameter_type_list ')' | '(' identifier_list ')' | '(' ')' ); + def declarator_suffix(self, ): + + declarator_suffix_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 24): + return + + # C.g:255:2: ( '[' constant_expression ']' | '[' ']' | '(' parameter_type_list ')' | '(' identifier_list ')' | '(' ')' ) + alt35 = 5 + LA35_0 = self.input.LA(1) + + if (LA35_0 == 63) : + LA35_1 = self.input.LA(2) + + if (LA35_1 == 64) : + alt35 = 2 + elif ((IDENTIFIER <= LA35_1 <= FLOATING_POINT_LITERAL) or LA35_1 == 61 or LA35_1 == 65 or (67 <= LA35_1 <= 68) or (71 <= LA35_1 <= 73) or (76 <= LA35_1 <= 78)) : + alt35 = 1 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("254:1: declarator_suffix : ( '[' constant_expression ']' | '[' ']' | '(' parameter_type_list ')' | '(' identifier_list ')' | '(' ')' );", 35, 1, self.input) + + raise nvae + + elif (LA35_0 == 61) : + LA35 = self.input.LA(2) + if LA35 == 62: + alt35 = 5 + elif LA35 == IDENTIFIER: + LA35_17 = self.input.LA(3) + + if (self.synpred72()) : + alt35 = 3 + elif (self.synpred73()) : + alt35 = 4 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("254:1: declarator_suffix : ( '[' constant_expression ']' | '[' ']' | '(' parameter_type_list ')' | '(' identifier_list ')' | '(' ')' );", 35, 17, self.input) + + raise nvae + + elif LA35 == 29 or LA35 == 30 or LA35 == 31 or LA35 == 32 or LA35 == 33 or LA35 == 34 or LA35 == 35 or LA35 == 36 or LA35 == 37 or LA35 == 38 or LA35 == 39 or LA35 == 40 or LA35 == 41 or LA35 == 42 or LA35 == 45 or LA35 == 46 or LA35 == 48 or LA35 == 49 or LA35 == 50 or LA35 == 51 or LA35 == 52 or LA35 == 53 or LA35 == 54 or LA35 == 55 or LA35 == 56 or LA35 == 57 or LA35 == 58 or LA35 == 59 or LA35 == 60 or LA35 == 65: + alt35 = 3 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("254:1: declarator_suffix : ( '[' constant_expression ']' | '[' ']' | '(' parameter_type_list ')' | '(' identifier_list ')' | '(' ')' );", 35, 2, self.input) + + raise nvae + + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("254:1: declarator_suffix : ( '[' constant_expression ']' | '[' ']' | '(' parameter_type_list ')' | '(' identifier_list ')' | '(' ')' );", 35, 0, self.input) + + raise nvae + + if alt35 == 1: + # C.g:255:6: '[' constant_expression ']' + self.match(self.input, 63, self.FOLLOW_63_in_declarator_suffix837) + if self.failed: + return + self.following.append(self.FOLLOW_constant_expression_in_declarator_suffix839) + self.constant_expression() + self.following.pop() + if self.failed: + return + self.match(self.input, 64, self.FOLLOW_64_in_declarator_suffix841) + if self.failed: + return + + + elif alt35 == 2: + # C.g:256:9: '[' ']' + self.match(self.input, 63, self.FOLLOW_63_in_declarator_suffix851) + if self.failed: + return + self.match(self.input, 64, self.FOLLOW_64_in_declarator_suffix853) + if self.failed: + return + + + elif alt35 == 3: + # C.g:257:9: '(' parameter_type_list ')' + self.match(self.input, 61, self.FOLLOW_61_in_declarator_suffix863) + if self.failed: + return + self.following.append(self.FOLLOW_parameter_type_list_in_declarator_suffix865) + self.parameter_type_list() + self.following.pop() + if self.failed: + return + self.match(self.input, 62, self.FOLLOW_62_in_declarator_suffix867) + if self.failed: + return + + + elif alt35 == 4: + # C.g:258:9: '(' identifier_list ')' + self.match(self.input, 61, self.FOLLOW_61_in_declarator_suffix877) + if self.failed: + return + self.following.append(self.FOLLOW_identifier_list_in_declarator_suffix879) + self.identifier_list() + self.following.pop() + if self.failed: + return + self.match(self.input, 62, self.FOLLOW_62_in_declarator_suffix881) + if self.failed: + return + + + elif alt35 == 5: + # C.g:259:9: '(' ')' + self.match(self.input, 61, self.FOLLOW_61_in_declarator_suffix891) + if self.failed: + return + self.match(self.input, 62, self.FOLLOW_62_in_declarator_suffix893) + if self.failed: + return + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 24, declarator_suffix_StartIndex) + + pass + + return + + # $ANTLR end declarator_suffix + + + # $ANTLR start pointer + # C.g:262:1: pointer : ( '*' ( type_qualifier )+ ( pointer )? | '*' pointer | '*' ); + def pointer(self, ): + + pointer_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 25): + return + + # C.g:263:2: ( '*' ( type_qualifier )+ ( pointer )? | '*' pointer | '*' ) + alt38 = 3 + LA38_0 = self.input.LA(1) + + if (LA38_0 == 65) : + LA38 = self.input.LA(2) + if LA38 == 58: + LA38_2 = self.input.LA(3) + + if (self.synpred76()) : + alt38 = 1 + elif (True) : + alt38 = 3 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("262:1: pointer : ( '*' ( type_qualifier )+ ( pointer )? | '*' pointer | '*' );", 38, 2, self.input) + + raise nvae + + elif LA38 == 59: + LA38_3 = self.input.LA(3) + + if (self.synpred76()) : + alt38 = 1 + elif (True) : + alt38 = 3 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("262:1: pointer : ( '*' ( type_qualifier )+ ( pointer )? | '*' pointer | '*' );", 38, 3, self.input) + + raise nvae + + elif LA38 == 60: + LA38_4 = self.input.LA(3) + + if (self.synpred76()) : + alt38 = 1 + elif (True) : + alt38 = 3 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("262:1: pointer : ( '*' ( type_qualifier )+ ( pointer )? | '*' pointer | '*' );", 38, 4, self.input) + + raise nvae + + elif LA38 == EOF or LA38 == IDENTIFIER or LA38 == 25 or LA38 == 26 or LA38 == 27 or LA38 == 28 or LA38 == 29 or LA38 == 30 or LA38 == 31 or LA38 == 32 or LA38 == 33 or LA38 == 34 or LA38 == 35 or LA38 == 36 or LA38 == 37 or LA38 == 38 or LA38 == 39 or LA38 == 40 or LA38 == 41 or LA38 == 42 or LA38 == 43 or LA38 == 45 or LA38 == 46 or LA38 == 47 or LA38 == 48 or LA38 == 61 or LA38 == 62 or LA38 == 63: + alt38 = 3 + elif LA38 == 53: + LA38_20 = self.input.LA(3) + + if (self.synpred76()) : + alt38 = 1 + elif (True) : + alt38 = 3 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("262:1: pointer : ( '*' ( type_qualifier )+ ( pointer )? | '*' pointer | '*' );", 38, 20, self.input) + + raise nvae + + elif LA38 == 49 or LA38 == 50 or LA38 == 51 or LA38 == 52 or LA38 == 54 or LA38 == 55 or LA38 == 56 or LA38 == 57: + LA38_28 = self.input.LA(3) + + if (self.synpred76()) : + alt38 = 1 + elif (True) : + alt38 = 3 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("262:1: pointer : ( '*' ( type_qualifier )+ ( pointer )? | '*' pointer | '*' );", 38, 28, self.input) + + raise nvae + + elif LA38 == 65: + LA38_29 = self.input.LA(3) + + if (self.synpred77()) : + alt38 = 2 + elif (True) : + alt38 = 3 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("262:1: pointer : ( '*' ( type_qualifier )+ ( pointer )? | '*' pointer | '*' );", 38, 29, self.input) + + raise nvae + + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("262:1: pointer : ( '*' ( type_qualifier )+ ( pointer )? | '*' pointer | '*' );", 38, 1, self.input) + + raise nvae + + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("262:1: pointer : ( '*' ( type_qualifier )+ ( pointer )? | '*' pointer | '*' );", 38, 0, self.input) + + raise nvae + + if alt38 == 1: + # C.g:263:4: '*' ( type_qualifier )+ ( pointer )? + self.match(self.input, 65, self.FOLLOW_65_in_pointer904) + if self.failed: + return + # C.g:263:8: ( type_qualifier )+ + cnt36 = 0 + while True: #loop36 + alt36 = 2 + LA36 = self.input.LA(1) + if LA36 == 58: + LA36_2 = self.input.LA(2) + + if (self.synpred74()) : + alt36 = 1 + + + elif LA36 == 59: + LA36_3 = self.input.LA(2) + + if (self.synpred74()) : + alt36 = 1 + + + elif LA36 == 60: + LA36_4 = self.input.LA(2) + + if (self.synpred74()) : + alt36 = 1 + + + elif LA36 == 53: + LA36_20 = self.input.LA(2) + + if (self.synpred74()) : + alt36 = 1 + + + elif LA36 == 49 or LA36 == 50 or LA36 == 51 or LA36 == 52 or LA36 == 54 or LA36 == 55 or LA36 == 56 or LA36 == 57: + LA36_28 = self.input.LA(2) + + if (self.synpred74()) : + alt36 = 1 + + + + if alt36 == 1: + # C.g:0:0: type_qualifier + self.following.append(self.FOLLOW_type_qualifier_in_pointer906) + self.type_qualifier() + self.following.pop() + if self.failed: + return + + + else: + if cnt36 >= 1: + break #loop36 + + if self.backtracking > 0: + self.failed = True + return + + eee = EarlyExitException(36, self.input) + raise eee + + cnt36 += 1 + + + # C.g:263:24: ( pointer )? + alt37 = 2 + LA37_0 = self.input.LA(1) + + if (LA37_0 == 65) : + LA37_1 = self.input.LA(2) + + if (self.synpred75()) : + alt37 = 1 + if alt37 == 1: + # C.g:0:0: pointer + self.following.append(self.FOLLOW_pointer_in_pointer909) + self.pointer() + self.following.pop() + if self.failed: + return + + + + + + elif alt38 == 2: + # C.g:264:4: '*' pointer + self.match(self.input, 65, self.FOLLOW_65_in_pointer915) + if self.failed: + return + self.following.append(self.FOLLOW_pointer_in_pointer917) + self.pointer() + self.following.pop() + if self.failed: + return + + + elif alt38 == 3: + # C.g:265:4: '*' + self.match(self.input, 65, self.FOLLOW_65_in_pointer922) + if self.failed: + return + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 25, pointer_StartIndex) + + pass + + return + + # $ANTLR end pointer + + + # $ANTLR start parameter_type_list + # C.g:268:1: parameter_type_list : parameter_list ( ',' ( 'OPTIONAL' )? '...' )? ; + def parameter_type_list(self, ): + + parameter_type_list_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 26): + return + + # C.g:269:2: ( parameter_list ( ',' ( 'OPTIONAL' )? '...' )? ) + # C.g:269:4: parameter_list ( ',' ( 'OPTIONAL' )? '...' )? + self.following.append(self.FOLLOW_parameter_list_in_parameter_type_list933) + self.parameter_list() + self.following.pop() + if self.failed: + return + # C.g:269:19: ( ',' ( 'OPTIONAL' )? '...' )? + alt40 = 2 + LA40_0 = self.input.LA(1) + + if (LA40_0 == 27) : + alt40 = 1 + if alt40 == 1: + # C.g:269:20: ',' ( 'OPTIONAL' )? '...' + self.match(self.input, 27, self.FOLLOW_27_in_parameter_type_list936) + if self.failed: + return + # C.g:269:24: ( 'OPTIONAL' )? + alt39 = 2 + LA39_0 = self.input.LA(1) + + if (LA39_0 == 53) : + alt39 = 1 + if alt39 == 1: + # C.g:269:25: 'OPTIONAL' + self.match(self.input, 53, self.FOLLOW_53_in_parameter_type_list939) + if self.failed: + return + + + + self.match(self.input, 66, self.FOLLOW_66_in_parameter_type_list943) + if self.failed: + return + + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 26, parameter_type_list_StartIndex) + + pass + + return + + # $ANTLR end parameter_type_list + + + # $ANTLR start parameter_list + # C.g:272:1: parameter_list : parameter_declaration ( ',' ( 'OPTIONAL' )? parameter_declaration )* ; + def parameter_list(self, ): + + parameter_list_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 27): + return + + # C.g:273:2: ( parameter_declaration ( ',' ( 'OPTIONAL' )? parameter_declaration )* ) + # C.g:273:4: parameter_declaration ( ',' ( 'OPTIONAL' )? parameter_declaration )* + self.following.append(self.FOLLOW_parameter_declaration_in_parameter_list956) + self.parameter_declaration() + self.following.pop() + if self.failed: + return + # C.g:273:26: ( ',' ( 'OPTIONAL' )? parameter_declaration )* + while True: #loop42 + alt42 = 2 + LA42_0 = self.input.LA(1) + + if (LA42_0 == 27) : + LA42_1 = self.input.LA(2) + + if (LA42_1 == 53) : + LA42_3 = self.input.LA(3) + + if (self.synpred81()) : + alt42 = 1 + + + elif (LA42_1 == IDENTIFIER or (29 <= LA42_1 <= 42) or (45 <= LA42_1 <= 46) or (48 <= LA42_1 <= 52) or (54 <= LA42_1 <= 60) or LA42_1 == 65) : + alt42 = 1 + + + + + if alt42 == 1: + # C.g:273:27: ',' ( 'OPTIONAL' )? parameter_declaration + self.match(self.input, 27, self.FOLLOW_27_in_parameter_list959) + if self.failed: + return + # C.g:273:31: ( 'OPTIONAL' )? + alt41 = 2 + LA41_0 = self.input.LA(1) + + if (LA41_0 == 53) : + LA41_1 = self.input.LA(2) + + if (self.synpred80()) : + alt41 = 1 + if alt41 == 1: + # C.g:273:32: 'OPTIONAL' + self.match(self.input, 53, self.FOLLOW_53_in_parameter_list962) + if self.failed: + return + + + + self.following.append(self.FOLLOW_parameter_declaration_in_parameter_list966) + self.parameter_declaration() + self.following.pop() + if self.failed: + return + + + else: + break #loop42 + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 27, parameter_list_StartIndex) + + pass + + return + + # $ANTLR end parameter_list + + + # $ANTLR start parameter_declaration + # C.g:276:1: parameter_declaration : ( declaration_specifiers ( declarator | abstract_declarator )* ( 'OPTIONAL' )? | ( pointer )* IDENTIFIER ); + def parameter_declaration(self, ): + + parameter_declaration_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 28): + return + + # C.g:277:2: ( declaration_specifiers ( declarator | abstract_declarator )* ( 'OPTIONAL' )? | ( pointer )* IDENTIFIER ) + alt46 = 2 + LA46 = self.input.LA(1) + if LA46 == 29 or LA46 == 30 or LA46 == 31 or LA46 == 32 or LA46 == 33 or LA46 == 34 or LA46 == 35 or LA46 == 36 or LA46 == 37 or LA46 == 38 or LA46 == 39 or LA46 == 40 or LA46 == 41 or LA46 == 42 or LA46 == 45 or LA46 == 46 or LA46 == 48 or LA46 == 49 or LA46 == 50 or LA46 == 51 or LA46 == 52 or LA46 == 53 or LA46 == 54 or LA46 == 55 or LA46 == 56 or LA46 == 57 or LA46 == 58 or LA46 == 59 or LA46 == 60: + alt46 = 1 + elif LA46 == IDENTIFIER: + LA46_13 = self.input.LA(2) + + if (self.synpred85()) : + alt46 = 1 + elif (True) : + alt46 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("276:1: parameter_declaration : ( declaration_specifiers ( declarator | abstract_declarator )* ( 'OPTIONAL' )? | ( pointer )* IDENTIFIER );", 46, 13, self.input) + + raise nvae + + elif LA46 == 65: + alt46 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("276:1: parameter_declaration : ( declaration_specifiers ( declarator | abstract_declarator )* ( 'OPTIONAL' )? | ( pointer )* IDENTIFIER );", 46, 0, self.input) + + raise nvae + + if alt46 == 1: + # C.g:277:4: declaration_specifiers ( declarator | abstract_declarator )* ( 'OPTIONAL' )? + self.following.append(self.FOLLOW_declaration_specifiers_in_parameter_declaration979) + self.declaration_specifiers() + self.following.pop() + if self.failed: + return + # C.g:277:27: ( declarator | abstract_declarator )* + while True: #loop43 + alt43 = 3 + LA43 = self.input.LA(1) + if LA43 == 65: + LA43_5 = self.input.LA(2) + + if (self.synpred82()) : + alt43 = 1 + elif (self.synpred83()) : + alt43 = 2 + + + elif LA43 == IDENTIFIER or LA43 == 58 or LA43 == 59 or LA43 == 60: + alt43 = 1 + elif LA43 == 61: + LA43 = self.input.LA(2) + if LA43 == 29 or LA43 == 30 or LA43 == 31 or LA43 == 32 or LA43 == 33 or LA43 == 34 or LA43 == 35 or LA43 == 36 or LA43 == 37 or LA43 == 38 or LA43 == 39 or LA43 == 40 or LA43 == 41 or LA43 == 42 or LA43 == 45 or LA43 == 46 or LA43 == 48 or LA43 == 49 or LA43 == 50 or LA43 == 51 or LA43 == 52 or LA43 == 53 or LA43 == 54 or LA43 == 55 or LA43 == 56 or LA43 == 57 or LA43 == 62 or LA43 == 63: + alt43 = 2 + elif LA43 == IDENTIFIER: + LA43_37 = self.input.LA(3) + + if (self.synpred82()) : + alt43 = 1 + elif (self.synpred83()) : + alt43 = 2 + + + elif LA43 == 58: + LA43_38 = self.input.LA(3) + + if (self.synpred82()) : + alt43 = 1 + elif (self.synpred83()) : + alt43 = 2 + + + elif LA43 == 65: + LA43_39 = self.input.LA(3) + + if (self.synpred82()) : + alt43 = 1 + elif (self.synpred83()) : + alt43 = 2 + + + elif LA43 == 59: + LA43_40 = self.input.LA(3) + + if (self.synpred82()) : + alt43 = 1 + elif (self.synpred83()) : + alt43 = 2 + + + elif LA43 == 60: + LA43_41 = self.input.LA(3) + + if (self.synpred82()) : + alt43 = 1 + elif (self.synpred83()) : + alt43 = 2 + + + elif LA43 == 61: + LA43_43 = self.input.LA(3) + + if (self.synpred82()) : + alt43 = 1 + elif (self.synpred83()) : + alt43 = 2 + + + + elif LA43 == 63: + alt43 = 2 + + if alt43 == 1: + # C.g:277:28: declarator + self.following.append(self.FOLLOW_declarator_in_parameter_declaration982) + self.declarator() + self.following.pop() + if self.failed: + return + + + elif alt43 == 2: + # C.g:277:39: abstract_declarator + self.following.append(self.FOLLOW_abstract_declarator_in_parameter_declaration984) + self.abstract_declarator() + self.following.pop() + if self.failed: + return + + + else: + break #loop43 + + + # C.g:277:61: ( 'OPTIONAL' )? + alt44 = 2 + LA44_0 = self.input.LA(1) + + if (LA44_0 == 53) : + alt44 = 1 + if alt44 == 1: + # C.g:277:62: 'OPTIONAL' + self.match(self.input, 53, self.FOLLOW_53_in_parameter_declaration989) + if self.failed: + return + + + + + + elif alt46 == 2: + # C.g:279:4: ( pointer )* IDENTIFIER + # C.g:279:4: ( pointer )* + while True: #loop45 + alt45 = 2 + LA45_0 = self.input.LA(1) + + if (LA45_0 == 65) : + alt45 = 1 + + + if alt45 == 1: + # C.g:0:0: pointer + self.following.append(self.FOLLOW_pointer_in_parameter_declaration998) + self.pointer() + self.following.pop() + if self.failed: + return + + + else: + break #loop45 + + + self.match(self.input, IDENTIFIER, self.FOLLOW_IDENTIFIER_in_parameter_declaration1001) + if self.failed: + return + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 28, parameter_declaration_StartIndex) + + pass + + return + + # $ANTLR end parameter_declaration + + + # $ANTLR start identifier_list + # C.g:282:1: identifier_list : IDENTIFIER ( ',' IDENTIFIER )* ; + def identifier_list(self, ): + + identifier_list_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 29): + return + + # C.g:283:2: ( IDENTIFIER ( ',' IDENTIFIER )* ) + # C.g:283:4: IDENTIFIER ( ',' IDENTIFIER )* + self.match(self.input, IDENTIFIER, self.FOLLOW_IDENTIFIER_in_identifier_list1012) + if self.failed: + return + # C.g:284:2: ( ',' IDENTIFIER )* + while True: #loop47 + alt47 = 2 + LA47_0 = self.input.LA(1) + + if (LA47_0 == 27) : + alt47 = 1 + + + if alt47 == 1: + # C.g:284:3: ',' IDENTIFIER + self.match(self.input, 27, self.FOLLOW_27_in_identifier_list1016) + if self.failed: + return + self.match(self.input, IDENTIFIER, self.FOLLOW_IDENTIFIER_in_identifier_list1018) + if self.failed: + return + + + else: + break #loop47 + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 29, identifier_list_StartIndex) + + pass + + return + + # $ANTLR end identifier_list + + + # $ANTLR start type_name + # C.g:287:1: type_name : ( specifier_qualifier_list ( abstract_declarator )? | type_id ); + def type_name(self, ): + + type_name_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 30): + return + + # C.g:288:2: ( specifier_qualifier_list ( abstract_declarator )? | type_id ) + alt49 = 2 + LA49_0 = self.input.LA(1) + + if ((34 <= LA49_0 <= 42) or (45 <= LA49_0 <= 46) or (48 <= LA49_0 <= 60)) : + alt49 = 1 + elif (LA49_0 == IDENTIFIER) : + LA49_13 = self.input.LA(2) + + if (self.synpred89()) : + alt49 = 1 + elif (True) : + alt49 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("287:1: type_name : ( specifier_qualifier_list ( abstract_declarator )? | type_id );", 49, 13, self.input) + + raise nvae + + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("287:1: type_name : ( specifier_qualifier_list ( abstract_declarator )? | type_id );", 49, 0, self.input) + + raise nvae + + if alt49 == 1: + # C.g:288:4: specifier_qualifier_list ( abstract_declarator )? + self.following.append(self.FOLLOW_specifier_qualifier_list_in_type_name1031) + self.specifier_qualifier_list() + self.following.pop() + if self.failed: + return + # C.g:288:29: ( abstract_declarator )? + alt48 = 2 + LA48_0 = self.input.LA(1) + + if (LA48_0 == 61 or LA48_0 == 63 or LA48_0 == 65) : + alt48 = 1 + if alt48 == 1: + # C.g:0:0: abstract_declarator + self.following.append(self.FOLLOW_abstract_declarator_in_type_name1033) + self.abstract_declarator() + self.following.pop() + if self.failed: + return + + + + + + elif alt49 == 2: + # C.g:289:4: type_id + self.following.append(self.FOLLOW_type_id_in_type_name1039) + self.type_id() + self.following.pop() + if self.failed: + return + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 30, type_name_StartIndex) + + pass + + return + + # $ANTLR end type_name + + + # $ANTLR start abstract_declarator + # C.g:292:1: abstract_declarator : ( pointer ( direct_abstract_declarator )? | direct_abstract_declarator ); + def abstract_declarator(self, ): + + abstract_declarator_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 31): + return + + # C.g:293:2: ( pointer ( direct_abstract_declarator )? | direct_abstract_declarator ) + alt51 = 2 + LA51_0 = self.input.LA(1) + + if (LA51_0 == 65) : + alt51 = 1 + elif (LA51_0 == 61 or LA51_0 == 63) : + alt51 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("292:1: abstract_declarator : ( pointer ( direct_abstract_declarator )? | direct_abstract_declarator );", 51, 0, self.input) + + raise nvae + + if alt51 == 1: + # C.g:293:4: pointer ( direct_abstract_declarator )? + self.following.append(self.FOLLOW_pointer_in_abstract_declarator1050) + self.pointer() + self.following.pop() + if self.failed: + return + # C.g:293:12: ( direct_abstract_declarator )? + alt50 = 2 + LA50_0 = self.input.LA(1) + + if (LA50_0 == 61) : + LA50 = self.input.LA(2) + if LA50 == 62: + LA50_12 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 58: + LA50_13 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 65: + LA50_14 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 59: + LA50_15 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 60: + LA50_16 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == IDENTIFIER: + LA50_17 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 61: + LA50_18 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 29 or LA50 == 30 or LA50 == 31 or LA50 == 32 or LA50 == 33: + LA50_19 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 34: + LA50_20 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 35: + LA50_21 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 36: + LA50_22 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 37: + LA50_23 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 38: + LA50_24 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 39: + LA50_25 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 40: + LA50_26 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 41: + LA50_27 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 42: + LA50_28 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 45 or LA50 == 46: + LA50_29 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 48: + LA50_30 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 49 or LA50 == 50 or LA50 == 51 or LA50 == 52 or LA50 == 53 or LA50 == 54 or LA50 == 55 or LA50 == 56 or LA50 == 57: + LA50_31 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 63: + LA50_32 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif (LA50_0 == 63) : + LA50 = self.input.LA(2) + if LA50 == 64: + LA50_33 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 61: + LA50_34 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == IDENTIFIER: + LA50_35 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == HEX_LITERAL: + LA50_36 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == OCTAL_LITERAL: + LA50_37 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == DECIMAL_LITERAL: + LA50_38 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == CHARACTER_LITERAL: + LA50_39 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == STRING_LITERAL: + LA50_40 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == FLOATING_POINT_LITERAL: + LA50_41 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 71: + LA50_42 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 72: + LA50_43 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 65 or LA50 == 67 or LA50 == 68 or LA50 == 76 or LA50 == 77 or LA50 == 78: + LA50_44 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + elif LA50 == 73: + LA50_45 = self.input.LA(3) + + if (self.synpred90()) : + alt50 = 1 + if alt50 == 1: + # C.g:0:0: direct_abstract_declarator + self.following.append(self.FOLLOW_direct_abstract_declarator_in_abstract_declarator1052) + self.direct_abstract_declarator() + self.following.pop() + if self.failed: + return + + + + + + elif alt51 == 2: + # C.g:294:4: direct_abstract_declarator + self.following.append(self.FOLLOW_direct_abstract_declarator_in_abstract_declarator1058) + self.direct_abstract_declarator() + self.following.pop() + if self.failed: + return + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 31, abstract_declarator_StartIndex) + + pass + + return + + # $ANTLR end abstract_declarator + + + # $ANTLR start direct_abstract_declarator + # C.g:297:1: direct_abstract_declarator : ( '(' abstract_declarator ')' | abstract_declarator_suffix ) ( abstract_declarator_suffix )* ; + def direct_abstract_declarator(self, ): + + direct_abstract_declarator_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 32): + return + + # C.g:298:2: ( ( '(' abstract_declarator ')' | abstract_declarator_suffix ) ( abstract_declarator_suffix )* ) + # C.g:298:4: ( '(' abstract_declarator ')' | abstract_declarator_suffix ) ( abstract_declarator_suffix )* + # C.g:298:4: ( '(' abstract_declarator ')' | abstract_declarator_suffix ) + alt52 = 2 + LA52_0 = self.input.LA(1) + + if (LA52_0 == 61) : + LA52 = self.input.LA(2) + if LA52 == IDENTIFIER or LA52 == 29 or LA52 == 30 or LA52 == 31 or LA52 == 32 or LA52 == 33 or LA52 == 34 or LA52 == 35 or LA52 == 36 or LA52 == 37 or LA52 == 38 or LA52 == 39 or LA52 == 40 or LA52 == 41 or LA52 == 42 or LA52 == 45 or LA52 == 46 or LA52 == 48 or LA52 == 49 or LA52 == 50 or LA52 == 51 or LA52 == 52 or LA52 == 53 or LA52 == 54 or LA52 == 55 or LA52 == 56 or LA52 == 57 or LA52 == 58 or LA52 == 59 or LA52 == 60 or LA52 == 62: + alt52 = 2 + elif LA52 == 65: + LA52_18 = self.input.LA(3) + + if (self.synpred92()) : + alt52 = 1 + elif (True) : + alt52 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("298:4: ( '(' abstract_declarator ')' | abstract_declarator_suffix )", 52, 18, self.input) + + raise nvae + + elif LA52 == 61 or LA52 == 63: + alt52 = 1 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("298:4: ( '(' abstract_declarator ')' | abstract_declarator_suffix )", 52, 1, self.input) + + raise nvae + + elif (LA52_0 == 63) : + alt52 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("298:4: ( '(' abstract_declarator ')' | abstract_declarator_suffix )", 52, 0, self.input) + + raise nvae + + if alt52 == 1: + # C.g:298:6: '(' abstract_declarator ')' + self.match(self.input, 61, self.FOLLOW_61_in_direct_abstract_declarator1071) + if self.failed: + return + self.following.append(self.FOLLOW_abstract_declarator_in_direct_abstract_declarator1073) + self.abstract_declarator() + self.following.pop() + if self.failed: + return + self.match(self.input, 62, self.FOLLOW_62_in_direct_abstract_declarator1075) + if self.failed: + return + + + elif alt52 == 2: + # C.g:298:36: abstract_declarator_suffix + self.following.append(self.FOLLOW_abstract_declarator_suffix_in_direct_abstract_declarator1079) + self.abstract_declarator_suffix() + self.following.pop() + if self.failed: + return + + + + # C.g:298:65: ( abstract_declarator_suffix )* + while True: #loop53 + alt53 = 2 + LA53_0 = self.input.LA(1) + + if (LA53_0 == 61) : + LA53 = self.input.LA(2) + if LA53 == 62: + LA53_12 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == 58: + LA53_13 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == 65: + LA53_14 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == 59: + LA53_15 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == 60: + LA53_16 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == IDENTIFIER: + LA53_17 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == 29 or LA53 == 30 or LA53 == 31 or LA53 == 32 or LA53 == 33: + LA53_19 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == 34: + LA53_20 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == 35: + LA53_21 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == 36: + LA53_22 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == 37: + LA53_23 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == 38: + LA53_24 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == 39: + LA53_25 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == 40: + LA53_26 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == 41: + LA53_27 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == 42: + LA53_28 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == 45 or LA53 == 46: + LA53_29 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == 48: + LA53_30 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == 49 or LA53 == 50 or LA53 == 51 or LA53 == 52 or LA53 == 53 or LA53 == 54 or LA53 == 55 or LA53 == 56 or LA53 == 57: + LA53_31 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + + elif (LA53_0 == 63) : + LA53 = self.input.LA(2) + if LA53 == 64: + LA53_33 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == 61: + LA53_34 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == IDENTIFIER: + LA53_35 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == HEX_LITERAL: + LA53_36 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == OCTAL_LITERAL: + LA53_37 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == DECIMAL_LITERAL: + LA53_38 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == CHARACTER_LITERAL: + LA53_39 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == STRING_LITERAL: + LA53_40 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == FLOATING_POINT_LITERAL: + LA53_41 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == 71: + LA53_42 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == 72: + LA53_43 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == 65 or LA53 == 67 or LA53 == 68 or LA53 == 76 or LA53 == 77 or LA53 == 78: + LA53_44 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + elif LA53 == 73: + LA53_45 = self.input.LA(3) + + if (self.synpred93()) : + alt53 = 1 + + + + + + if alt53 == 1: + # C.g:0:0: abstract_declarator_suffix + self.following.append(self.FOLLOW_abstract_declarator_suffix_in_direct_abstract_declarator1083) + self.abstract_declarator_suffix() + self.following.pop() + if self.failed: + return + + + else: + break #loop53 + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 32, direct_abstract_declarator_StartIndex) + + pass + + return + + # $ANTLR end direct_abstract_declarator + + + # $ANTLR start abstract_declarator_suffix + # C.g:301:1: abstract_declarator_suffix : ( '[' ']' | '[' constant_expression ']' | '(' ')' | '(' parameter_type_list ')' ); + def abstract_declarator_suffix(self, ): + + abstract_declarator_suffix_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 33): + return + + # C.g:302:2: ( '[' ']' | '[' constant_expression ']' | '(' ')' | '(' parameter_type_list ')' ) + alt54 = 4 + LA54_0 = self.input.LA(1) + + if (LA54_0 == 63) : + LA54_1 = self.input.LA(2) + + if (LA54_1 == 64) : + alt54 = 1 + elif ((IDENTIFIER <= LA54_1 <= FLOATING_POINT_LITERAL) or LA54_1 == 61 or LA54_1 == 65 or (67 <= LA54_1 <= 68) or (71 <= LA54_1 <= 73) or (76 <= LA54_1 <= 78)) : + alt54 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("301:1: abstract_declarator_suffix : ( '[' ']' | '[' constant_expression ']' | '(' ')' | '(' parameter_type_list ')' );", 54, 1, self.input) + + raise nvae + + elif (LA54_0 == 61) : + LA54_2 = self.input.LA(2) + + if (LA54_2 == 62) : + alt54 = 3 + elif (LA54_2 == IDENTIFIER or (29 <= LA54_2 <= 42) or (45 <= LA54_2 <= 46) or (48 <= LA54_2 <= 60) or LA54_2 == 65) : + alt54 = 4 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("301:1: abstract_declarator_suffix : ( '[' ']' | '[' constant_expression ']' | '(' ')' | '(' parameter_type_list ')' );", 54, 2, self.input) + + raise nvae + + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("301:1: abstract_declarator_suffix : ( '[' ']' | '[' constant_expression ']' | '(' ')' | '(' parameter_type_list ')' );", 54, 0, self.input) + + raise nvae + + if alt54 == 1: + # C.g:302:4: '[' ']' + self.match(self.input, 63, self.FOLLOW_63_in_abstract_declarator_suffix1095) + if self.failed: + return + self.match(self.input, 64, self.FOLLOW_64_in_abstract_declarator_suffix1097) + if self.failed: + return + + + elif alt54 == 2: + # C.g:303:4: '[' constant_expression ']' + self.match(self.input, 63, self.FOLLOW_63_in_abstract_declarator_suffix1102) + if self.failed: + return + self.following.append(self.FOLLOW_constant_expression_in_abstract_declarator_suffix1104) + self.constant_expression() + self.following.pop() + if self.failed: + return + self.match(self.input, 64, self.FOLLOW_64_in_abstract_declarator_suffix1106) + if self.failed: + return + + + elif alt54 == 3: + # C.g:304:4: '(' ')' + self.match(self.input, 61, self.FOLLOW_61_in_abstract_declarator_suffix1111) + if self.failed: + return + self.match(self.input, 62, self.FOLLOW_62_in_abstract_declarator_suffix1113) + if self.failed: + return + + + elif alt54 == 4: + # C.g:305:4: '(' parameter_type_list ')' + self.match(self.input, 61, self.FOLLOW_61_in_abstract_declarator_suffix1118) + if self.failed: + return + self.following.append(self.FOLLOW_parameter_type_list_in_abstract_declarator_suffix1120) + self.parameter_type_list() + self.following.pop() + if self.failed: + return + self.match(self.input, 62, self.FOLLOW_62_in_abstract_declarator_suffix1122) + if self.failed: + return + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 33, abstract_declarator_suffix_StartIndex) + + pass + + return + + # $ANTLR end abstract_declarator_suffix + + + # $ANTLR start initializer + # C.g:308:1: initializer : ( assignment_expression | '{' initializer_list ( ',' )? '}' ); + def initializer(self, ): + + initializer_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 34): + return + + # C.g:310:2: ( assignment_expression | '{' initializer_list ( ',' )? '}' ) + alt56 = 2 + LA56_0 = self.input.LA(1) + + if ((IDENTIFIER <= LA56_0 <= FLOATING_POINT_LITERAL) or LA56_0 == 61 or LA56_0 == 65 or (67 <= LA56_0 <= 68) or (71 <= LA56_0 <= 73) or (76 <= LA56_0 <= 78)) : + alt56 = 1 + elif (LA56_0 == 43) : + alt56 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("308:1: initializer : ( assignment_expression | '{' initializer_list ( ',' )? '}' );", 56, 0, self.input) + + raise nvae + + if alt56 == 1: + # C.g:310:4: assignment_expression + self.following.append(self.FOLLOW_assignment_expression_in_initializer1135) + self.assignment_expression() + self.following.pop() + if self.failed: + return + + + elif alt56 == 2: + # C.g:311:4: '{' initializer_list ( ',' )? '}' + self.match(self.input, 43, self.FOLLOW_43_in_initializer1140) + if self.failed: + return + self.following.append(self.FOLLOW_initializer_list_in_initializer1142) + self.initializer_list() + self.following.pop() + if self.failed: + return + # C.g:311:25: ( ',' )? + alt55 = 2 + LA55_0 = self.input.LA(1) + + if (LA55_0 == 27) : + alt55 = 1 + if alt55 == 1: + # C.g:0:0: ',' + self.match(self.input, 27, self.FOLLOW_27_in_initializer1144) + if self.failed: + return + + + + self.match(self.input, 44, self.FOLLOW_44_in_initializer1147) + if self.failed: + return + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 34, initializer_StartIndex) + + pass + + return + + # $ANTLR end initializer + + + # $ANTLR start initializer_list + # C.g:314:1: initializer_list : initializer ( ',' initializer )* ; + def initializer_list(self, ): + + initializer_list_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 35): + return + + # C.g:315:2: ( initializer ( ',' initializer )* ) + # C.g:315:4: initializer ( ',' initializer )* + self.following.append(self.FOLLOW_initializer_in_initializer_list1158) + self.initializer() + self.following.pop() + if self.failed: + return + # C.g:315:16: ( ',' initializer )* + while True: #loop57 + alt57 = 2 + LA57_0 = self.input.LA(1) + + if (LA57_0 == 27) : + LA57_1 = self.input.LA(2) + + if ((IDENTIFIER <= LA57_1 <= FLOATING_POINT_LITERAL) or LA57_1 == 43 or LA57_1 == 61 or LA57_1 == 65 or (67 <= LA57_1 <= 68) or (71 <= LA57_1 <= 73) or (76 <= LA57_1 <= 78)) : + alt57 = 1 + + + + + if alt57 == 1: + # C.g:315:17: ',' initializer + self.match(self.input, 27, self.FOLLOW_27_in_initializer_list1161) + if self.failed: + return + self.following.append(self.FOLLOW_initializer_in_initializer_list1163) + self.initializer() + self.following.pop() + if self.failed: + return + + + else: + break #loop57 + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 35, initializer_list_StartIndex) + + pass + + return + + # $ANTLR end initializer_list + + class argument_expression_list_return(object): + def __init__(self): + self.start = None + self.stop = None + + + + # $ANTLR start argument_expression_list + # C.g:320:1: argument_expression_list : assignment_expression ( 'OPTIONAL' )? ( ',' assignment_expression ( 'OPTIONAL' )? )* ; + def argument_expression_list(self, ): + + retval = self.argument_expression_list_return() + retval.start = self.input.LT(1) + argument_expression_list_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 36): + return retval + + # C.g:321:2: ( assignment_expression ( 'OPTIONAL' )? ( ',' assignment_expression ( 'OPTIONAL' )? )* ) + # C.g:321:6: assignment_expression ( 'OPTIONAL' )? ( ',' assignment_expression ( 'OPTIONAL' )? )* + self.following.append(self.FOLLOW_assignment_expression_in_argument_expression_list1181) + self.assignment_expression() + self.following.pop() + if self.failed: + return retval + # C.g:321:28: ( 'OPTIONAL' )? + alt58 = 2 + LA58_0 = self.input.LA(1) + + if (LA58_0 == 53) : + alt58 = 1 + if alt58 == 1: + # C.g:321:29: 'OPTIONAL' + self.match(self.input, 53, self.FOLLOW_53_in_argument_expression_list1184) + if self.failed: + return retval + + + + # C.g:321:42: ( ',' assignment_expression ( 'OPTIONAL' )? )* + while True: #loop60 + alt60 = 2 + LA60_0 = self.input.LA(1) + + if (LA60_0 == 27) : + alt60 = 1 + + + if alt60 == 1: + # C.g:321:43: ',' assignment_expression ( 'OPTIONAL' )? + self.match(self.input, 27, self.FOLLOW_27_in_argument_expression_list1189) + if self.failed: + return retval + self.following.append(self.FOLLOW_assignment_expression_in_argument_expression_list1191) + self.assignment_expression() + self.following.pop() + if self.failed: + return retval + # C.g:321:69: ( 'OPTIONAL' )? + alt59 = 2 + LA59_0 = self.input.LA(1) + + if (LA59_0 == 53) : + alt59 = 1 + if alt59 == 1: + # C.g:321:70: 'OPTIONAL' + self.match(self.input, 53, self.FOLLOW_53_in_argument_expression_list1194) + if self.failed: + return retval + + + + + + else: + break #loop60 + + + + + + retval.stop = self.input.LT(-1) + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 36, argument_expression_list_StartIndex) + + pass + + return retval + + # $ANTLR end argument_expression_list + + + # $ANTLR start additive_expression + # C.g:324:1: additive_expression : ( multiplicative_expression ) ( '+' multiplicative_expression | '-' multiplicative_expression )* ; + def additive_expression(self, ): + + additive_expression_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 37): + return + + # C.g:325:2: ( ( multiplicative_expression ) ( '+' multiplicative_expression | '-' multiplicative_expression )* ) + # C.g:325:4: ( multiplicative_expression ) ( '+' multiplicative_expression | '-' multiplicative_expression )* + # C.g:325:4: ( multiplicative_expression ) + # C.g:325:5: multiplicative_expression + self.following.append(self.FOLLOW_multiplicative_expression_in_additive_expression1210) + self.multiplicative_expression() + self.following.pop() + if self.failed: + return + + + + # C.g:325:32: ( '+' multiplicative_expression | '-' multiplicative_expression )* + while True: #loop61 + alt61 = 3 + LA61_0 = self.input.LA(1) + + if (LA61_0 == 67) : + alt61 = 1 + elif (LA61_0 == 68) : + alt61 = 2 + + + if alt61 == 1: + # C.g:325:33: '+' multiplicative_expression + self.match(self.input, 67, self.FOLLOW_67_in_additive_expression1214) + if self.failed: + return + self.following.append(self.FOLLOW_multiplicative_expression_in_additive_expression1216) + self.multiplicative_expression() + self.following.pop() + if self.failed: + return + + + elif alt61 == 2: + # C.g:325:65: '-' multiplicative_expression + self.match(self.input, 68, self.FOLLOW_68_in_additive_expression1220) + if self.failed: + return + self.following.append(self.FOLLOW_multiplicative_expression_in_additive_expression1222) + self.multiplicative_expression() + self.following.pop() + if self.failed: + return + + + else: + break #loop61 + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 37, additive_expression_StartIndex) + + pass + + return + + # $ANTLR end additive_expression + + + # $ANTLR start multiplicative_expression + # C.g:328:1: multiplicative_expression : ( cast_expression ) ( '*' cast_expression | '/' cast_expression | '%' cast_expression )* ; + def multiplicative_expression(self, ): + + multiplicative_expression_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 38): + return + + # C.g:329:2: ( ( cast_expression ) ( '*' cast_expression | '/' cast_expression | '%' cast_expression )* ) + # C.g:329:4: ( cast_expression ) ( '*' cast_expression | '/' cast_expression | '%' cast_expression )* + # C.g:329:4: ( cast_expression ) + # C.g:329:5: cast_expression + self.following.append(self.FOLLOW_cast_expression_in_multiplicative_expression1236) + self.cast_expression() + self.following.pop() + if self.failed: + return + + + + # C.g:329:22: ( '*' cast_expression | '/' cast_expression | '%' cast_expression )* + while True: #loop62 + alt62 = 4 + LA62 = self.input.LA(1) + if LA62 == 65: + alt62 = 1 + elif LA62 == 69: + alt62 = 2 + elif LA62 == 70: + alt62 = 3 + + if alt62 == 1: + # C.g:329:23: '*' cast_expression + self.match(self.input, 65, self.FOLLOW_65_in_multiplicative_expression1240) + if self.failed: + return + self.following.append(self.FOLLOW_cast_expression_in_multiplicative_expression1242) + self.cast_expression() + self.following.pop() + if self.failed: + return + + + elif alt62 == 2: + # C.g:329:45: '/' cast_expression + self.match(self.input, 69, self.FOLLOW_69_in_multiplicative_expression1246) + if self.failed: + return + self.following.append(self.FOLLOW_cast_expression_in_multiplicative_expression1248) + self.cast_expression() + self.following.pop() + if self.failed: + return + + + elif alt62 == 3: + # C.g:329:67: '%' cast_expression + self.match(self.input, 70, self.FOLLOW_70_in_multiplicative_expression1252) + if self.failed: + return + self.following.append(self.FOLLOW_cast_expression_in_multiplicative_expression1254) + self.cast_expression() + self.following.pop() + if self.failed: + return + + + else: + break #loop62 + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 38, multiplicative_expression_StartIndex) + + pass + + return + + # $ANTLR end multiplicative_expression + + + # $ANTLR start cast_expression + # C.g:332:1: cast_expression : ( '(' type_name ')' cast_expression | unary_expression ); + def cast_expression(self, ): + + cast_expression_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 39): + return + + # C.g:333:2: ( '(' type_name ')' cast_expression | unary_expression ) + alt63 = 2 + LA63_0 = self.input.LA(1) + + if (LA63_0 == 61) : + LA63 = self.input.LA(2) + if LA63 == IDENTIFIER: + LA63_13 = self.input.LA(3) + + if (self.synpred108()) : + alt63 = 1 + elif (True) : + alt63 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("332:1: cast_expression : ( '(' type_name ')' cast_expression | unary_expression );", 63, 13, self.input) + + raise nvae + + elif LA63 == HEX_LITERAL or LA63 == OCTAL_LITERAL or LA63 == DECIMAL_LITERAL or LA63 == CHARACTER_LITERAL or LA63 == STRING_LITERAL or LA63 == FLOATING_POINT_LITERAL or LA63 == 61 or LA63 == 65 or LA63 == 67 or LA63 == 68 or LA63 == 71 or LA63 == 72 or LA63 == 73 or LA63 == 76 or LA63 == 77 or LA63 == 78: + alt63 = 2 + elif LA63 == 34 or LA63 == 35 or LA63 == 36 or LA63 == 37 or LA63 == 38 or LA63 == 39 or LA63 == 40 or LA63 == 41 or LA63 == 42 or LA63 == 45 or LA63 == 46 or LA63 == 48 or LA63 == 49 or LA63 == 50 or LA63 == 51 or LA63 == 52 or LA63 == 53 or LA63 == 54 or LA63 == 55 or LA63 == 56 or LA63 == 57 or LA63 == 58 or LA63 == 59 or LA63 == 60: + alt63 = 1 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("332:1: cast_expression : ( '(' type_name ')' cast_expression | unary_expression );", 63, 1, self.input) + + raise nvae + + elif ((IDENTIFIER <= LA63_0 <= FLOATING_POINT_LITERAL) or LA63_0 == 65 or (67 <= LA63_0 <= 68) or (71 <= LA63_0 <= 73) or (76 <= LA63_0 <= 78)) : + alt63 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("332:1: cast_expression : ( '(' type_name ')' cast_expression | unary_expression );", 63, 0, self.input) + + raise nvae + + if alt63 == 1: + # C.g:333:4: '(' type_name ')' cast_expression + self.match(self.input, 61, self.FOLLOW_61_in_cast_expression1267) + if self.failed: + return + self.following.append(self.FOLLOW_type_name_in_cast_expression1269) + self.type_name() + self.following.pop() + if self.failed: + return + self.match(self.input, 62, self.FOLLOW_62_in_cast_expression1271) + if self.failed: + return + self.following.append(self.FOLLOW_cast_expression_in_cast_expression1273) + self.cast_expression() + self.following.pop() + if self.failed: + return + + + elif alt63 == 2: + # C.g:334:4: unary_expression + self.following.append(self.FOLLOW_unary_expression_in_cast_expression1278) + self.unary_expression() + self.following.pop() + if self.failed: + return + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 39, cast_expression_StartIndex) + + pass + + return + + # $ANTLR end cast_expression + + + # $ANTLR start unary_expression + # C.g:337:1: unary_expression : ( postfix_expression | '++' unary_expression | '--' unary_expression | unary_operator cast_expression | 'sizeof' unary_expression | 'sizeof' '(' type_name ')' ); + def unary_expression(self, ): + + unary_expression_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 40): + return + + # C.g:338:2: ( postfix_expression | '++' unary_expression | '--' unary_expression | unary_operator cast_expression | 'sizeof' unary_expression | 'sizeof' '(' type_name ')' ) + alt64 = 6 + LA64 = self.input.LA(1) + if LA64 == IDENTIFIER or LA64 == HEX_LITERAL or LA64 == OCTAL_LITERAL or LA64 == DECIMAL_LITERAL or LA64 == CHARACTER_LITERAL or LA64 == STRING_LITERAL or LA64 == FLOATING_POINT_LITERAL or LA64 == 61: + alt64 = 1 + elif LA64 == 71: + alt64 = 2 + elif LA64 == 72: + alt64 = 3 + elif LA64 == 65 or LA64 == 67 or LA64 == 68 or LA64 == 76 or LA64 == 77 or LA64 == 78: + alt64 = 4 + elif LA64 == 73: + LA64_12 = self.input.LA(2) + + if (LA64_12 == 61) : + LA64_13 = self.input.LA(3) + + if (self.synpred113()) : + alt64 = 5 + elif (True) : + alt64 = 6 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("337:1: unary_expression : ( postfix_expression | '++' unary_expression | '--' unary_expression | unary_operator cast_expression | 'sizeof' unary_expression | 'sizeof' '(' type_name ')' );", 64, 13, self.input) + + raise nvae + + elif ((IDENTIFIER <= LA64_12 <= FLOATING_POINT_LITERAL) or LA64_12 == 65 or (67 <= LA64_12 <= 68) or (71 <= LA64_12 <= 73) or (76 <= LA64_12 <= 78)) : + alt64 = 5 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("337:1: unary_expression : ( postfix_expression | '++' unary_expression | '--' unary_expression | unary_operator cast_expression | 'sizeof' unary_expression | 'sizeof' '(' type_name ')' );", 64, 12, self.input) + + raise nvae + + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("337:1: unary_expression : ( postfix_expression | '++' unary_expression | '--' unary_expression | unary_operator cast_expression | 'sizeof' unary_expression | 'sizeof' '(' type_name ')' );", 64, 0, self.input) + + raise nvae + + if alt64 == 1: + # C.g:338:4: postfix_expression + self.following.append(self.FOLLOW_postfix_expression_in_unary_expression1289) + self.postfix_expression() + self.following.pop() + if self.failed: + return + + + elif alt64 == 2: + # C.g:339:4: '++' unary_expression + self.match(self.input, 71, self.FOLLOW_71_in_unary_expression1294) + if self.failed: + return + self.following.append(self.FOLLOW_unary_expression_in_unary_expression1296) + self.unary_expression() + self.following.pop() + if self.failed: + return + + + elif alt64 == 3: + # C.g:340:4: '--' unary_expression + self.match(self.input, 72, self.FOLLOW_72_in_unary_expression1301) + if self.failed: + return + self.following.append(self.FOLLOW_unary_expression_in_unary_expression1303) + self.unary_expression() + self.following.pop() + if self.failed: + return + + + elif alt64 == 4: + # C.g:341:4: unary_operator cast_expression + self.following.append(self.FOLLOW_unary_operator_in_unary_expression1308) + self.unary_operator() + self.following.pop() + if self.failed: + return + self.following.append(self.FOLLOW_cast_expression_in_unary_expression1310) + self.cast_expression() + self.following.pop() + if self.failed: + return + + + elif alt64 == 5: + # C.g:342:4: 'sizeof' unary_expression + self.match(self.input, 73, self.FOLLOW_73_in_unary_expression1315) + if self.failed: + return + self.following.append(self.FOLLOW_unary_expression_in_unary_expression1317) + self.unary_expression() + self.following.pop() + if self.failed: + return + + + elif alt64 == 6: + # C.g:343:4: 'sizeof' '(' type_name ')' + self.match(self.input, 73, self.FOLLOW_73_in_unary_expression1322) + if self.failed: + return + self.match(self.input, 61, self.FOLLOW_61_in_unary_expression1324) + if self.failed: + return + self.following.append(self.FOLLOW_type_name_in_unary_expression1326) + self.type_name() + self.following.pop() + if self.failed: + return + self.match(self.input, 62, self.FOLLOW_62_in_unary_expression1328) + if self.failed: + return + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 40, unary_expression_StartIndex) + + pass + + return + + # $ANTLR end unary_expression + + + # $ANTLR start postfix_expression + # C.g:346:1: postfix_expression : p= primary_expression ( '[' expression ']' | '(' a= ')' | '(' c= argument_expression_list b= ')' | '(' macro_parameter_list ')' | '.' x= IDENTIFIER | '*' y= IDENTIFIER | '->' z= IDENTIFIER | '++' | '--' )* ; + def postfix_expression(self, ): + self.postfix_expression_stack.append(postfix_expression_scope()) + postfix_expression_StartIndex = self.input.index() + a = None + b = None + x = None + y = None + z = None + p = None + + c = None + + + + self.postfix_expression_stack[-1].FuncCallText = '' + + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 41): + return + + # C.g:353:2: (p= primary_expression ( '[' expression ']' | '(' a= ')' | '(' c= argument_expression_list b= ')' | '(' macro_parameter_list ')' | '.' x= IDENTIFIER | '*' y= IDENTIFIER | '->' z= IDENTIFIER | '++' | '--' )* ) + # C.g:353:6: p= primary_expression ( '[' expression ']' | '(' a= ')' | '(' c= argument_expression_list b= ')' | '(' macro_parameter_list ')' | '.' x= IDENTIFIER | '*' y= IDENTIFIER | '->' z= IDENTIFIER | '++' | '--' )* + self.following.append(self.FOLLOW_primary_expression_in_postfix_expression1352) + p = self.primary_expression() + self.following.pop() + if self.failed: + return + if self.backtracking == 0: + self.postfix_expression_stack[-1].FuncCallText += self.input.toString(p.start,p.stop) + + # C.g:354:9: ( '[' expression ']' | '(' a= ')' | '(' c= argument_expression_list b= ')' | '(' macro_parameter_list ')' | '.' x= IDENTIFIER | '*' y= IDENTIFIER | '->' z= IDENTIFIER | '++' | '--' )* + while True: #loop65 + alt65 = 10 + LA65 = self.input.LA(1) + if LA65 == 65: + LA65_1 = self.input.LA(2) + + if (LA65_1 == IDENTIFIER) : + LA65_30 = self.input.LA(3) + + if (self.synpred119()) : + alt65 = 6 + + + + + elif LA65 == 63: + alt65 = 1 + elif LA65 == 61: + LA65 = self.input.LA(2) + if LA65 == 62: + alt65 = 2 + elif LA65 == IDENTIFIER: + LA65_43 = self.input.LA(3) + + if (self.synpred116()) : + alt65 = 3 + elif (self.synpred117()) : + alt65 = 4 + + + elif LA65 == HEX_LITERAL or LA65 == OCTAL_LITERAL or LA65 == DECIMAL_LITERAL or LA65 == CHARACTER_LITERAL or LA65 == STRING_LITERAL or LA65 == FLOATING_POINT_LITERAL or LA65 == 61 or LA65 == 67 or LA65 == 68 or LA65 == 71 or LA65 == 72 or LA65 == 73 or LA65 == 76 or LA65 == 77 or LA65 == 78: + alt65 = 3 + elif LA65 == 65: + LA65_53 = self.input.LA(3) + + if (self.synpred116()) : + alt65 = 3 + elif (self.synpred117()) : + alt65 = 4 + + + elif LA65 == 29 or LA65 == 30 or LA65 == 31 or LA65 == 32 or LA65 == 33 or LA65 == 34 or LA65 == 35 or LA65 == 36 or LA65 == 37 or LA65 == 38 or LA65 == 39 or LA65 == 40 or LA65 == 41 or LA65 == 42 or LA65 == 45 or LA65 == 46 or LA65 == 48 or LA65 == 49 or LA65 == 50 or LA65 == 51 or LA65 == 52 or LA65 == 53 or LA65 == 54 or LA65 == 55 or LA65 == 56 or LA65 == 57 or LA65 == 58 or LA65 == 59 or LA65 == 60: + alt65 = 4 + + elif LA65 == 74: + alt65 = 5 + elif LA65 == 75: + alt65 = 7 + elif LA65 == 71: + alt65 = 8 + elif LA65 == 72: + alt65 = 9 + + if alt65 == 1: + # C.g:354:13: '[' expression ']' + self.match(self.input, 63, self.FOLLOW_63_in_postfix_expression1368) + if self.failed: + return + self.following.append(self.FOLLOW_expression_in_postfix_expression1370) + self.expression() + self.following.pop() + if self.failed: + return + self.match(self.input, 64, self.FOLLOW_64_in_postfix_expression1372) + if self.failed: + return + + + elif alt65 == 2: + # C.g:355:13: '(' a= ')' + self.match(self.input, 61, self.FOLLOW_61_in_postfix_expression1386) + if self.failed: + return + a = self.input.LT(1) + self.match(self.input, 62, self.FOLLOW_62_in_postfix_expression1390) + if self.failed: + return + if self.backtracking == 0: + self.StoreFunctionCalling(p.start.line, p.start.charPositionInLine, a.line, a.charPositionInLine, self.postfix_expression_stack[-1].FuncCallText, '') + + + + elif alt65 == 3: + # C.g:356:13: '(' c= argument_expression_list b= ')' + self.match(self.input, 61, self.FOLLOW_61_in_postfix_expression1405) + if self.failed: + return + self.following.append(self.FOLLOW_argument_expression_list_in_postfix_expression1409) + c = self.argument_expression_list() + self.following.pop() + if self.failed: + return + b = self.input.LT(1) + self.match(self.input, 62, self.FOLLOW_62_in_postfix_expression1413) + if self.failed: + return + if self.backtracking == 0: + self.StoreFunctionCalling(p.start.line, p.start.charPositionInLine, b.line, b.charPositionInLine, self.postfix_expression_stack[-1].FuncCallText, self.input.toString(c.start,c.stop)) + + + + elif alt65 == 4: + # C.g:357:13: '(' macro_parameter_list ')' + self.match(self.input, 61, self.FOLLOW_61_in_postfix_expression1429) + if self.failed: + return + self.following.append(self.FOLLOW_macro_parameter_list_in_postfix_expression1431) + self.macro_parameter_list() + self.following.pop() + if self.failed: + return + self.match(self.input, 62, self.FOLLOW_62_in_postfix_expression1433) + if self.failed: + return + + + elif alt65 == 5: + # C.g:358:13: '.' x= IDENTIFIER + self.match(self.input, 74, self.FOLLOW_74_in_postfix_expression1447) + if self.failed: + return + x = self.input.LT(1) + self.match(self.input, IDENTIFIER, self.FOLLOW_IDENTIFIER_in_postfix_expression1451) + if self.failed: + return + if self.backtracking == 0: + self.postfix_expression_stack[-1].FuncCallText += '.' + x.text + + + + elif alt65 == 6: + # C.g:359:13: '*' y= IDENTIFIER + self.match(self.input, 65, self.FOLLOW_65_in_postfix_expression1467) + if self.failed: + return + y = self.input.LT(1) + self.match(self.input, IDENTIFIER, self.FOLLOW_IDENTIFIER_in_postfix_expression1471) + if self.failed: + return + if self.backtracking == 0: + self.postfix_expression_stack[-1].FuncCallText = y.text + + + + elif alt65 == 7: + # C.g:360:13: '->' z= IDENTIFIER + self.match(self.input, 75, self.FOLLOW_75_in_postfix_expression1487) + if self.failed: + return + z = self.input.LT(1) + self.match(self.input, IDENTIFIER, self.FOLLOW_IDENTIFIER_in_postfix_expression1491) + if self.failed: + return + if self.backtracking == 0: + self.postfix_expression_stack[-1].FuncCallText += '->' + z.text + + + + elif alt65 == 8: + # C.g:361:13: '++' + self.match(self.input, 71, self.FOLLOW_71_in_postfix_expression1507) + if self.failed: + return + + + elif alt65 == 9: + # C.g:362:13: '--' + self.match(self.input, 72, self.FOLLOW_72_in_postfix_expression1521) + if self.failed: + return + + + else: + break #loop65 + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 41, postfix_expression_StartIndex) + + self.postfix_expression_stack.pop() + pass + + return + + # $ANTLR end postfix_expression + + + # $ANTLR start macro_parameter_list + # C.g:366:1: macro_parameter_list : parameter_declaration ( ',' parameter_declaration )* ; + def macro_parameter_list(self, ): + + macro_parameter_list_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 42): + return + + # C.g:367:2: ( parameter_declaration ( ',' parameter_declaration )* ) + # C.g:367:4: parameter_declaration ( ',' parameter_declaration )* + self.following.append(self.FOLLOW_parameter_declaration_in_macro_parameter_list1544) + self.parameter_declaration() + self.following.pop() + if self.failed: + return + # C.g:367:26: ( ',' parameter_declaration )* + while True: #loop66 + alt66 = 2 + LA66_0 = self.input.LA(1) + + if (LA66_0 == 27) : + alt66 = 1 + + + if alt66 == 1: + # C.g:367:27: ',' parameter_declaration + self.match(self.input, 27, self.FOLLOW_27_in_macro_parameter_list1547) + if self.failed: + return + self.following.append(self.FOLLOW_parameter_declaration_in_macro_parameter_list1549) + self.parameter_declaration() + self.following.pop() + if self.failed: + return + + + else: + break #loop66 + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 42, macro_parameter_list_StartIndex) + + pass + + return + + # $ANTLR end macro_parameter_list + + + # $ANTLR start unary_operator + # C.g:370:1: unary_operator : ( '&' | '*' | '+' | '-' | '~' | '!' ); + def unary_operator(self, ): + + unary_operator_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 43): + return + + # C.g:371:2: ( '&' | '*' | '+' | '-' | '~' | '!' ) + # C.g: + if self.input.LA(1) == 65 or (67 <= self.input.LA(1) <= 68) or (76 <= self.input.LA(1) <= 78): + self.input.consume(); + self.errorRecovery = False + self.failed = False + + else: + if self.backtracking > 0: + self.failed = True + return + + mse = MismatchedSetException(None, self.input) + self.recoverFromMismatchedSet( + self.input, mse, self.FOLLOW_set_in_unary_operator0 + ) + raise mse + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 43, unary_operator_StartIndex) + + pass + + return + + # $ANTLR end unary_operator + + class primary_expression_return(object): + def __init__(self): + self.start = None + self.stop = None + + + + # $ANTLR start primary_expression + # C.g:379:1: primary_expression : ( IDENTIFIER | constant | '(' expression ')' ); + def primary_expression(self, ): + + retval = self.primary_expression_return() + retval.start = self.input.LT(1) + primary_expression_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 44): + return retval + + # C.g:380:2: ( IDENTIFIER | constant | '(' expression ')' ) + alt67 = 3 + LA67 = self.input.LA(1) + if LA67 == IDENTIFIER: + LA67_1 = self.input.LA(2) + + if (LA67_1 == IDENTIFIER or LA67_1 == STRING_LITERAL) : + alt67 = 2 + elif (LA67_1 == EOF or LA67_1 == 25 or (27 <= LA67_1 <= 28) or LA67_1 == 44 or LA67_1 == 47 or LA67_1 == 53 or (61 <= LA67_1 <= 65) or (67 <= LA67_1 <= 72) or (74 <= LA67_1 <= 76) or (79 <= LA67_1 <= 101)) : + alt67 = 1 + else: + if self.backtracking > 0: + self.failed = True + return retval + + nvae = NoViableAltException("379:1: primary_expression : ( IDENTIFIER | constant | '(' expression ')' );", 67, 1, self.input) + + raise nvae + + elif LA67 == HEX_LITERAL or LA67 == OCTAL_LITERAL or LA67 == DECIMAL_LITERAL or LA67 == CHARACTER_LITERAL or LA67 == STRING_LITERAL or LA67 == FLOATING_POINT_LITERAL: + alt67 = 2 + elif LA67 == 61: + alt67 = 3 + else: + if self.backtracking > 0: + self.failed = True + return retval + + nvae = NoViableAltException("379:1: primary_expression : ( IDENTIFIER | constant | '(' expression ')' );", 67, 0, self.input) + + raise nvae + + if alt67 == 1: + # C.g:380:4: IDENTIFIER + self.match(self.input, IDENTIFIER, self.FOLLOW_IDENTIFIER_in_primary_expression1598) + if self.failed: + return retval + + + elif alt67 == 2: + # C.g:381:4: constant + self.following.append(self.FOLLOW_constant_in_primary_expression1603) + self.constant() + self.following.pop() + if self.failed: + return retval + + + elif alt67 == 3: + # C.g:382:4: '(' expression ')' + self.match(self.input, 61, self.FOLLOW_61_in_primary_expression1608) + if self.failed: + return retval + self.following.append(self.FOLLOW_expression_in_primary_expression1610) + self.expression() + self.following.pop() + if self.failed: + return retval + self.match(self.input, 62, self.FOLLOW_62_in_primary_expression1612) + if self.failed: + return retval + + + retval.stop = self.input.LT(-1) + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 44, primary_expression_StartIndex) + + pass + + return retval + + # $ANTLR end primary_expression + + + # $ANTLR start constant + # C.g:385:1: constant : ( HEX_LITERAL | OCTAL_LITERAL | DECIMAL_LITERAL | CHARACTER_LITERAL | ( ( IDENTIFIER )* ( STRING_LITERAL )+ )+ ( IDENTIFIER )* | FLOATING_POINT_LITERAL ); + def constant(self, ): + + constant_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 45): + return + + # C.g:386:5: ( HEX_LITERAL | OCTAL_LITERAL | DECIMAL_LITERAL | CHARACTER_LITERAL | ( ( IDENTIFIER )* ( STRING_LITERAL )+ )+ ( IDENTIFIER )* | FLOATING_POINT_LITERAL ) + alt72 = 6 + LA72 = self.input.LA(1) + if LA72 == HEX_LITERAL: + alt72 = 1 + elif LA72 == OCTAL_LITERAL: + alt72 = 2 + elif LA72 == DECIMAL_LITERAL: + alt72 = 3 + elif LA72 == CHARACTER_LITERAL: + alt72 = 4 + elif LA72 == IDENTIFIER or LA72 == STRING_LITERAL: + alt72 = 5 + elif LA72 == FLOATING_POINT_LITERAL: + alt72 = 6 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("385:1: constant : ( HEX_LITERAL | OCTAL_LITERAL | DECIMAL_LITERAL | CHARACTER_LITERAL | ( ( IDENTIFIER )* ( STRING_LITERAL )+ )+ ( IDENTIFIER )* | FLOATING_POINT_LITERAL );", 72, 0, self.input) + + raise nvae + + if alt72 == 1: + # C.g:386:9: HEX_LITERAL + self.match(self.input, HEX_LITERAL, self.FOLLOW_HEX_LITERAL_in_constant1628) + if self.failed: + return + + + elif alt72 == 2: + # C.g:387:9: OCTAL_LITERAL + self.match(self.input, OCTAL_LITERAL, self.FOLLOW_OCTAL_LITERAL_in_constant1638) + if self.failed: + return + + + elif alt72 == 3: + # C.g:388:9: DECIMAL_LITERAL + self.match(self.input, DECIMAL_LITERAL, self.FOLLOW_DECIMAL_LITERAL_in_constant1648) + if self.failed: + return + + + elif alt72 == 4: + # C.g:389:7: CHARACTER_LITERAL + self.match(self.input, CHARACTER_LITERAL, self.FOLLOW_CHARACTER_LITERAL_in_constant1656) + if self.failed: + return + + + elif alt72 == 5: + # C.g:390:7: ( ( IDENTIFIER )* ( STRING_LITERAL )+ )+ ( IDENTIFIER )* + # C.g:390:7: ( ( IDENTIFIER )* ( STRING_LITERAL )+ )+ + cnt70 = 0 + while True: #loop70 + alt70 = 2 + LA70_0 = self.input.LA(1) + + if (LA70_0 == IDENTIFIER) : + LA70_1 = self.input.LA(2) + + if (LA70_1 == IDENTIFIER) : + LA70_61 = self.input.LA(3) + + if (self.synpred137()) : + alt70 = 1 + + + elif (LA70_1 == STRING_LITERAL) : + alt70 = 1 + + + elif (LA70_0 == STRING_LITERAL) : + alt70 = 1 + + + if alt70 == 1: + # C.g:390:8: ( IDENTIFIER )* ( STRING_LITERAL )+ + # C.g:390:8: ( IDENTIFIER )* + while True: #loop68 + alt68 = 2 + LA68_0 = self.input.LA(1) + + if (LA68_0 == IDENTIFIER) : + alt68 = 1 + + + if alt68 == 1: + # C.g:0:0: IDENTIFIER + self.match(self.input, IDENTIFIER, self.FOLLOW_IDENTIFIER_in_constant1665) + if self.failed: + return + + + else: + break #loop68 + + + # C.g:390:20: ( STRING_LITERAL )+ + cnt69 = 0 + while True: #loop69 + alt69 = 2 + LA69_0 = self.input.LA(1) + + if (LA69_0 == STRING_LITERAL) : + LA69_31 = self.input.LA(2) + + if (self.synpred136()) : + alt69 = 1 + + + + + if alt69 == 1: + # C.g:0:0: STRING_LITERAL + self.match(self.input, STRING_LITERAL, self.FOLLOW_STRING_LITERAL_in_constant1668) + if self.failed: + return + + + else: + if cnt69 >= 1: + break #loop69 + + if self.backtracking > 0: + self.failed = True + return + + eee = EarlyExitException(69, self.input) + raise eee + + cnt69 += 1 + + + + + else: + if cnt70 >= 1: + break #loop70 + + if self.backtracking > 0: + self.failed = True + return + + eee = EarlyExitException(70, self.input) + raise eee + + cnt70 += 1 + + + # C.g:390:38: ( IDENTIFIER )* + while True: #loop71 + alt71 = 2 + LA71_0 = self.input.LA(1) + + if (LA71_0 == IDENTIFIER) : + alt71 = 1 + + + if alt71 == 1: + # C.g:0:0: IDENTIFIER + self.match(self.input, IDENTIFIER, self.FOLLOW_IDENTIFIER_in_constant1673) + if self.failed: + return + + + else: + break #loop71 + + + + + elif alt72 == 6: + # C.g:391:9: FLOATING_POINT_LITERAL + self.match(self.input, FLOATING_POINT_LITERAL, self.FOLLOW_FLOATING_POINT_LITERAL_in_constant1684) + if self.failed: + return + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 45, constant_StartIndex) + + pass + + return + + # $ANTLR end constant + + class expression_return(object): + def __init__(self): + self.start = None + self.stop = None + + + + # $ANTLR start expression + # C.g:396:1: expression : assignment_expression ( ',' assignment_expression )* ; + def expression(self, ): + + retval = self.expression_return() + retval.start = self.input.LT(1) + expression_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 46): + return retval + + # C.g:397:2: ( assignment_expression ( ',' assignment_expression )* ) + # C.g:397:4: assignment_expression ( ',' assignment_expression )* + self.following.append(self.FOLLOW_assignment_expression_in_expression1700) + self.assignment_expression() + self.following.pop() + if self.failed: + return retval + # C.g:397:26: ( ',' assignment_expression )* + while True: #loop73 + alt73 = 2 + LA73_0 = self.input.LA(1) + + if (LA73_0 == 27) : + alt73 = 1 + + + if alt73 == 1: + # C.g:397:27: ',' assignment_expression + self.match(self.input, 27, self.FOLLOW_27_in_expression1703) + if self.failed: + return retval + self.following.append(self.FOLLOW_assignment_expression_in_expression1705) + self.assignment_expression() + self.following.pop() + if self.failed: + return retval + + + else: + break #loop73 + + + + + + retval.stop = self.input.LT(-1) + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 46, expression_StartIndex) + + pass + + return retval + + # $ANTLR end expression + + + # $ANTLR start constant_expression + # C.g:400:1: constant_expression : conditional_expression ; + def constant_expression(self, ): + + constant_expression_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 47): + return + + # C.g:401:2: ( conditional_expression ) + # C.g:401:4: conditional_expression + self.following.append(self.FOLLOW_conditional_expression_in_constant_expression1718) + self.conditional_expression() + self.following.pop() + if self.failed: + return + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 47, constant_expression_StartIndex) + + pass + + return + + # $ANTLR end constant_expression + + + # $ANTLR start assignment_expression + # C.g:404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression ); + def assignment_expression(self, ): + + assignment_expression_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 48): + return + + # C.g:405:2: ( lvalue assignment_operator assignment_expression | conditional_expression ) + alt74 = 2 + LA74 = self.input.LA(1) + if LA74 == IDENTIFIER: + LA74 = self.input.LA(2) + if LA74 == STRING_LITERAL: + LA74_13 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 13, self.input) + + raise nvae + + elif LA74 == IDENTIFIER: + LA74_14 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 14, self.input) + + raise nvae + + elif LA74 == 63: + LA74_15 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 15, self.input) + + raise nvae + + elif LA74 == 61: + LA74_16 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 16, self.input) + + raise nvae + + elif LA74 == 74: + LA74_17 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 17, self.input) + + raise nvae + + elif LA74 == 65: + LA74_18 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 18, self.input) + + raise nvae + + elif LA74 == 75: + LA74_19 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 19, self.input) + + raise nvae + + elif LA74 == 71: + LA74_20 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 20, self.input) + + raise nvae + + elif LA74 == 72: + LA74_21 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 21, self.input) + + raise nvae + + elif LA74 == EOF or LA74 == 25 or LA74 == 27 or LA74 == 44 or LA74 == 47 or LA74 == 53 or LA74 == 62 or LA74 == 64 or LA74 == 67 or LA74 == 68 or LA74 == 69 or LA74 == 70 or LA74 == 76 or LA74 == 89 or LA74 == 90 or LA74 == 91 or LA74 == 92 or LA74 == 93 or LA74 == 94 or LA74 == 95 or LA74 == 96 or LA74 == 97 or LA74 == 98 or LA74 == 99 or LA74 == 100 or LA74 == 101: + alt74 = 2 + elif LA74 == 28 or LA74 == 79 or LA74 == 80 or LA74 == 81 or LA74 == 82 or LA74 == 83 or LA74 == 84 or LA74 == 85 or LA74 == 86 or LA74 == 87 or LA74 == 88: + alt74 = 1 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 1, self.input) + + raise nvae + + elif LA74 == HEX_LITERAL: + LA74 = self.input.LA(2) + if LA74 == 63: + LA74_44 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 44, self.input) + + raise nvae + + elif LA74 == 61: + LA74_45 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 45, self.input) + + raise nvae + + elif LA74 == 74: + LA74_46 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 46, self.input) + + raise nvae + + elif LA74 == 65: + LA74_47 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 47, self.input) + + raise nvae + + elif LA74 == 75: + LA74_48 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 48, self.input) + + raise nvae + + elif LA74 == 71: + LA74_49 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 49, self.input) + + raise nvae + + elif LA74 == 72: + LA74_50 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 50, self.input) + + raise nvae + + elif LA74 == 28 or LA74 == 79 or LA74 == 80 or LA74 == 81 or LA74 == 82 or LA74 == 83 or LA74 == 84 or LA74 == 85 or LA74 == 86 or LA74 == 87 or LA74 == 88: + alt74 = 1 + elif LA74 == EOF or LA74 == 25 or LA74 == 27 or LA74 == 44 or LA74 == 47 or LA74 == 53 or LA74 == 62 or LA74 == 64 or LA74 == 67 or LA74 == 68 or LA74 == 69 or LA74 == 70 or LA74 == 76 or LA74 == 89 or LA74 == 90 or LA74 == 91 or LA74 == 92 or LA74 == 93 or LA74 == 94 or LA74 == 95 or LA74 == 96 or LA74 == 97 or LA74 == 98 or LA74 == 99 or LA74 == 100 or LA74 == 101: + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 2, self.input) + + raise nvae + + elif LA74 == OCTAL_LITERAL: + LA74 = self.input.LA(2) + if LA74 == 63: + LA74_73 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 73, self.input) + + raise nvae + + elif LA74 == 61: + LA74_74 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 74, self.input) + + raise nvae + + elif LA74 == 74: + LA74_75 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 75, self.input) + + raise nvae + + elif LA74 == 65: + LA74_76 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 76, self.input) + + raise nvae + + elif LA74 == 75: + LA74_77 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 77, self.input) + + raise nvae + + elif LA74 == 71: + LA74_78 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 78, self.input) + + raise nvae + + elif LA74 == 72: + LA74_79 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 79, self.input) + + raise nvae + + elif LA74 == 28 or LA74 == 79 or LA74 == 80 or LA74 == 81 or LA74 == 82 or LA74 == 83 or LA74 == 84 or LA74 == 85 or LA74 == 86 or LA74 == 87 or LA74 == 88: + alt74 = 1 + elif LA74 == EOF or LA74 == 25 or LA74 == 27 or LA74 == 44 or LA74 == 47 or LA74 == 53 or LA74 == 62 or LA74 == 64 or LA74 == 67 or LA74 == 68 or LA74 == 69 or LA74 == 70 or LA74 == 76 or LA74 == 89 or LA74 == 90 or LA74 == 91 or LA74 == 92 or LA74 == 93 or LA74 == 94 or LA74 == 95 or LA74 == 96 or LA74 == 97 or LA74 == 98 or LA74 == 99 or LA74 == 100 or LA74 == 101: + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 3, self.input) + + raise nvae + + elif LA74 == DECIMAL_LITERAL: + LA74 = self.input.LA(2) + if LA74 == 63: + LA74_102 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 102, self.input) + + raise nvae + + elif LA74 == 61: + LA74_103 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 103, self.input) + + raise nvae + + elif LA74 == 74: + LA74_104 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 104, self.input) + + raise nvae + + elif LA74 == 65: + LA74_105 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 105, self.input) + + raise nvae + + elif LA74 == 75: + LA74_106 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 106, self.input) + + raise nvae + + elif LA74 == 71: + LA74_107 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 107, self.input) + + raise nvae + + elif LA74 == 72: + LA74_108 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 108, self.input) + + raise nvae + + elif LA74 == EOF or LA74 == 25 or LA74 == 27 or LA74 == 44 or LA74 == 47 or LA74 == 53 or LA74 == 62 or LA74 == 64 or LA74 == 67 or LA74 == 68 or LA74 == 69 or LA74 == 70 or LA74 == 76 or LA74 == 89 or LA74 == 90 or LA74 == 91 or LA74 == 92 or LA74 == 93 or LA74 == 94 or LA74 == 95 or LA74 == 96 or LA74 == 97 or LA74 == 98 or LA74 == 99 or LA74 == 100 or LA74 == 101: + alt74 = 2 + elif LA74 == 28 or LA74 == 79 or LA74 == 80 or LA74 == 81 or LA74 == 82 or LA74 == 83 or LA74 == 84 or LA74 == 85 or LA74 == 86 or LA74 == 87 or LA74 == 88: + alt74 = 1 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 4, self.input) + + raise nvae + + elif LA74 == CHARACTER_LITERAL: + LA74 = self.input.LA(2) + if LA74 == 63: + LA74_131 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 131, self.input) + + raise nvae + + elif LA74 == 61: + LA74_132 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 132, self.input) + + raise nvae + + elif LA74 == 74: + LA74_133 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 133, self.input) + + raise nvae + + elif LA74 == 65: + LA74_134 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 134, self.input) + + raise nvae + + elif LA74 == 75: + LA74_135 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 135, self.input) + + raise nvae + + elif LA74 == 71: + LA74_136 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 136, self.input) + + raise nvae + + elif LA74 == 72: + LA74_137 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 137, self.input) + + raise nvae + + elif LA74 == 28 or LA74 == 79 or LA74 == 80 or LA74 == 81 or LA74 == 82 or LA74 == 83 or LA74 == 84 or LA74 == 85 or LA74 == 86 or LA74 == 87 or LA74 == 88: + alt74 = 1 + elif LA74 == EOF or LA74 == 25 or LA74 == 27 or LA74 == 44 or LA74 == 47 or LA74 == 53 or LA74 == 62 or LA74 == 64 or LA74 == 67 or LA74 == 68 or LA74 == 69 or LA74 == 70 or LA74 == 76 or LA74 == 89 or LA74 == 90 or LA74 == 91 or LA74 == 92 or LA74 == 93 or LA74 == 94 or LA74 == 95 or LA74 == 96 or LA74 == 97 or LA74 == 98 or LA74 == 99 or LA74 == 100 or LA74 == 101: + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 5, self.input) + + raise nvae + + elif LA74 == STRING_LITERAL: + LA74 = self.input.LA(2) + if LA74 == IDENTIFIER: + LA74_160 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 160, self.input) + + raise nvae + + elif LA74 == 63: + LA74_161 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 161, self.input) + + raise nvae + + elif LA74 == 61: + LA74_162 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 162, self.input) + + raise nvae + + elif LA74 == 74: + LA74_163 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 163, self.input) + + raise nvae + + elif LA74 == 65: + LA74_164 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 164, self.input) + + raise nvae + + elif LA74 == 75: + LA74_165 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 165, self.input) + + raise nvae + + elif LA74 == 71: + LA74_166 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 166, self.input) + + raise nvae + + elif LA74 == 72: + LA74_167 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 167, self.input) + + raise nvae + + elif LA74 == 28 or LA74 == 79 or LA74 == 80 or LA74 == 81 or LA74 == 82 or LA74 == 83 or LA74 == 84 or LA74 == 85 or LA74 == 86 or LA74 == 87 or LA74 == 88: + alt74 = 1 + elif LA74 == STRING_LITERAL: + LA74_169 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 169, self.input) + + raise nvae + + elif LA74 == EOF or LA74 == 25 or LA74 == 27 or LA74 == 44 or LA74 == 47 or LA74 == 53 or LA74 == 62 or LA74 == 64 or LA74 == 67 or LA74 == 68 or LA74 == 69 or LA74 == 70 or LA74 == 76 or LA74 == 89 or LA74 == 90 or LA74 == 91 or LA74 == 92 or LA74 == 93 or LA74 == 94 or LA74 == 95 or LA74 == 96 or LA74 == 97 or LA74 == 98 or LA74 == 99 or LA74 == 100 or LA74 == 101: + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 6, self.input) + + raise nvae + + elif LA74 == FLOATING_POINT_LITERAL: + LA74 = self.input.LA(2) + if LA74 == 63: + LA74_191 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 191, self.input) + + raise nvae + + elif LA74 == 61: + LA74_192 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 192, self.input) + + raise nvae + + elif LA74 == 74: + LA74_193 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 193, self.input) + + raise nvae + + elif LA74 == 65: + LA74_194 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 194, self.input) + + raise nvae + + elif LA74 == 75: + LA74_195 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 195, self.input) + + raise nvae + + elif LA74 == 71: + LA74_196 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 196, self.input) + + raise nvae + + elif LA74 == 72: + LA74_197 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 197, self.input) + + raise nvae + + elif LA74 == EOF or LA74 == 25 or LA74 == 27 or LA74 == 44 or LA74 == 47 or LA74 == 53 or LA74 == 62 or LA74 == 64 or LA74 == 67 or LA74 == 68 or LA74 == 69 or LA74 == 70 or LA74 == 76 or LA74 == 89 or LA74 == 90 or LA74 == 91 or LA74 == 92 or LA74 == 93 or LA74 == 94 or LA74 == 95 or LA74 == 96 or LA74 == 97 or LA74 == 98 or LA74 == 99 or LA74 == 100 or LA74 == 101: + alt74 = 2 + elif LA74 == 28 or LA74 == 79 or LA74 == 80 or LA74 == 81 or LA74 == 82 or LA74 == 83 or LA74 == 84 or LA74 == 85 or LA74 == 86 or LA74 == 87 or LA74 == 88: + alt74 = 1 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 7, self.input) + + raise nvae + + elif LA74 == 61: + LA74 = self.input.LA(2) + if LA74 == IDENTIFIER: + LA74_220 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 220, self.input) + + raise nvae + + elif LA74 == HEX_LITERAL: + LA74_221 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 221, self.input) + + raise nvae + + elif LA74 == OCTAL_LITERAL: + LA74_222 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 222, self.input) + + raise nvae + + elif LA74 == DECIMAL_LITERAL: + LA74_223 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 223, self.input) + + raise nvae + + elif LA74 == CHARACTER_LITERAL: + LA74_224 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 224, self.input) + + raise nvae + + elif LA74 == STRING_LITERAL: + LA74_225 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 225, self.input) + + raise nvae + + elif LA74 == FLOATING_POINT_LITERAL: + LA74_226 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 226, self.input) + + raise nvae + + elif LA74 == 61: + LA74_227 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 227, self.input) + + raise nvae + + elif LA74 == 71: + LA74_228 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 228, self.input) + + raise nvae + + elif LA74 == 72: + LA74_229 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 229, self.input) + + raise nvae + + elif LA74 == 65 or LA74 == 67 or LA74 == 68 or LA74 == 76 or LA74 == 77 or LA74 == 78: + LA74_230 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 230, self.input) + + raise nvae + + elif LA74 == 73: + LA74_231 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 231, self.input) + + raise nvae + + elif LA74 == 34 or LA74 == 35 or LA74 == 36 or LA74 == 37 or LA74 == 38 or LA74 == 39 or LA74 == 40 or LA74 == 41 or LA74 == 42 or LA74 == 45 or LA74 == 46 or LA74 == 48 or LA74 == 49 or LA74 == 50 or LA74 == 51 or LA74 == 52 or LA74 == 53 or LA74 == 54 or LA74 == 55 or LA74 == 56 or LA74 == 57 or LA74 == 58 or LA74 == 59 or LA74 == 60: + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 8, self.input) + + raise nvae + + elif LA74 == 71: + LA74 = self.input.LA(2) + if LA74 == IDENTIFIER: + LA74_244 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 244, self.input) + + raise nvae + + elif LA74 == HEX_LITERAL: + LA74_245 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 245, self.input) + + raise nvae + + elif LA74 == OCTAL_LITERAL: + LA74_246 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 246, self.input) + + raise nvae + + elif LA74 == DECIMAL_LITERAL: + LA74_247 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 247, self.input) + + raise nvae + + elif LA74 == CHARACTER_LITERAL: + LA74_248 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 248, self.input) + + raise nvae + + elif LA74 == STRING_LITERAL: + LA74_249 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 249, self.input) + + raise nvae + + elif LA74 == FLOATING_POINT_LITERAL: + LA74_250 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 250, self.input) + + raise nvae + + elif LA74 == 61: + LA74_251 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 251, self.input) + + raise nvae + + elif LA74 == 71: + LA74_252 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 252, self.input) + + raise nvae + + elif LA74 == 72: + LA74_253 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 253, self.input) + + raise nvae + + elif LA74 == 65 or LA74 == 67 or LA74 == 68 or LA74 == 76 or LA74 == 77 or LA74 == 78: + LA74_254 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 254, self.input) + + raise nvae + + elif LA74 == 73: + LA74_255 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 255, self.input) + + raise nvae + + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 9, self.input) + + raise nvae + + elif LA74 == 72: + LA74 = self.input.LA(2) + if LA74 == IDENTIFIER: + LA74_256 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 256, self.input) + + raise nvae + + elif LA74 == HEX_LITERAL: + LA74_257 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 257, self.input) + + raise nvae + + elif LA74 == OCTAL_LITERAL: + LA74_258 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 258, self.input) + + raise nvae + + elif LA74 == DECIMAL_LITERAL: + LA74_259 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 259, self.input) + + raise nvae + + elif LA74 == CHARACTER_LITERAL: + LA74_260 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 260, self.input) + + raise nvae + + elif LA74 == STRING_LITERAL: + LA74_261 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 261, self.input) + + raise nvae + + elif LA74 == FLOATING_POINT_LITERAL: + LA74_262 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 262, self.input) + + raise nvae + + elif LA74 == 61: + LA74_263 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 263, self.input) + + raise nvae + + elif LA74 == 71: + LA74_264 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 264, self.input) + + raise nvae + + elif LA74 == 72: + LA74_265 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 265, self.input) + + raise nvae + + elif LA74 == 65 or LA74 == 67 or LA74 == 68 or LA74 == 76 or LA74 == 77 or LA74 == 78: + LA74_266 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 266, self.input) + + raise nvae + + elif LA74 == 73: + LA74_267 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 267, self.input) + + raise nvae + + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 10, self.input) + + raise nvae + + elif LA74 == 65 or LA74 == 67 or LA74 == 68 or LA74 == 76 or LA74 == 77 or LA74 == 78: + LA74 = self.input.LA(2) + if LA74 == 61: + LA74_268 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 268, self.input) + + raise nvae + + elif LA74 == IDENTIFIER: + LA74_269 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 269, self.input) + + raise nvae + + elif LA74 == HEX_LITERAL: + LA74_270 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 270, self.input) + + raise nvae + + elif LA74 == OCTAL_LITERAL: + LA74_271 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 271, self.input) + + raise nvae + + elif LA74 == DECIMAL_LITERAL: + LA74_272 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 272, self.input) + + raise nvae + + elif LA74 == CHARACTER_LITERAL: + LA74_273 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 273, self.input) + + raise nvae + + elif LA74 == STRING_LITERAL: + LA74_274 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 274, self.input) + + raise nvae + + elif LA74 == FLOATING_POINT_LITERAL: + LA74_275 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 275, self.input) + + raise nvae + + elif LA74 == 71: + LA74_276 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 276, self.input) + + raise nvae + + elif LA74 == 72: + LA74_277 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 277, self.input) + + raise nvae + + elif LA74 == 65 or LA74 == 67 or LA74 == 68 or LA74 == 76 or LA74 == 77 or LA74 == 78: + LA74_278 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 278, self.input) + + raise nvae + + elif LA74 == 73: + LA74_279 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 279, self.input) + + raise nvae + + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 11, self.input) + + raise nvae + + elif LA74 == 73: + LA74 = self.input.LA(2) + if LA74 == 61: + LA74_280 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 280, self.input) + + raise nvae + + elif LA74 == IDENTIFIER: + LA74_281 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 281, self.input) + + raise nvae + + elif LA74 == HEX_LITERAL: + LA74_282 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 282, self.input) + + raise nvae + + elif LA74 == OCTAL_LITERAL: + LA74_283 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 283, self.input) + + raise nvae + + elif LA74 == DECIMAL_LITERAL: + LA74_284 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 284, self.input) + + raise nvae + + elif LA74 == CHARACTER_LITERAL: + LA74_285 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 285, self.input) + + raise nvae + + elif LA74 == STRING_LITERAL: + LA74_286 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 286, self.input) + + raise nvae + + elif LA74 == FLOATING_POINT_LITERAL: + LA74_287 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 287, self.input) + + raise nvae + + elif LA74 == 71: + LA74_288 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 288, self.input) + + raise nvae + + elif LA74 == 72: + LA74_289 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 289, self.input) + + raise nvae + + elif LA74 == 65 or LA74 == 67 or LA74 == 68 or LA74 == 76 or LA74 == 77 or LA74 == 78: + LA74_290 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 290, self.input) + + raise nvae + + elif LA74 == 73: + LA74_291 = self.input.LA(3) + + if (self.synpred141()) : + alt74 = 1 + elif (True) : + alt74 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 291, self.input) + + raise nvae + + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 12, self.input) + + raise nvae + + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("404:1: assignment_expression : ( lvalue assignment_operator assignment_expression | conditional_expression );", 74, 0, self.input) + + raise nvae + + if alt74 == 1: + # C.g:405:4: lvalue assignment_operator assignment_expression + self.following.append(self.FOLLOW_lvalue_in_assignment_expression1729) + self.lvalue() + self.following.pop() + if self.failed: + return + self.following.append(self.FOLLOW_assignment_operator_in_assignment_expression1731) + self.assignment_operator() + self.following.pop() + if self.failed: + return + self.following.append(self.FOLLOW_assignment_expression_in_assignment_expression1733) + self.assignment_expression() + self.following.pop() + if self.failed: + return + + + elif alt74 == 2: + # C.g:406:4: conditional_expression + self.following.append(self.FOLLOW_conditional_expression_in_assignment_expression1738) + self.conditional_expression() + self.following.pop() + if self.failed: + return + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 48, assignment_expression_StartIndex) + + pass + + return + + # $ANTLR end assignment_expression + + + # $ANTLR start lvalue + # C.g:409:1: lvalue : unary_expression ; + def lvalue(self, ): + + lvalue_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 49): + return + + # C.g:410:2: ( unary_expression ) + # C.g:410:4: unary_expression + self.following.append(self.FOLLOW_unary_expression_in_lvalue1750) + self.unary_expression() + self.following.pop() + if self.failed: + return + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 49, lvalue_StartIndex) + + pass + + return + + # $ANTLR end lvalue + + + # $ANTLR start assignment_operator + # C.g:413:1: assignment_operator : ( '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|=' ); + def assignment_operator(self, ): + + assignment_operator_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 50): + return + + # C.g:414:2: ( '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|=' ) + # C.g: + if self.input.LA(1) == 28 or (79 <= self.input.LA(1) <= 88): + self.input.consume(); + self.errorRecovery = False + self.failed = False + + else: + if self.backtracking > 0: + self.failed = True + return + + mse = MismatchedSetException(None, self.input) + self.recoverFromMismatchedSet( + self.input, mse, self.FOLLOW_set_in_assignment_operator0 + ) + raise mse + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 50, assignment_operator_StartIndex) + + pass + + return + + # $ANTLR end assignment_operator + + + # $ANTLR start conditional_expression + # C.g:427:1: conditional_expression : e= logical_or_expression ( '?' expression ':' conditional_expression )? ; + def conditional_expression(self, ): + + conditional_expression_StartIndex = self.input.index() + e = None + + + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 51): + return + + # C.g:428:2: (e= logical_or_expression ( '?' expression ':' conditional_expression )? ) + # C.g:428:4: e= logical_or_expression ( '?' expression ':' conditional_expression )? + self.following.append(self.FOLLOW_logical_or_expression_in_conditional_expression1824) + e = self.logical_or_expression() + self.following.pop() + if self.failed: + return + # C.g:428:28: ( '?' expression ':' conditional_expression )? + alt75 = 2 + LA75_0 = self.input.LA(1) + + if (LA75_0 == 89) : + alt75 = 1 + if alt75 == 1: + # C.g:428:29: '?' expression ':' conditional_expression + self.match(self.input, 89, self.FOLLOW_89_in_conditional_expression1827) + if self.failed: + return + self.following.append(self.FOLLOW_expression_in_conditional_expression1829) + self.expression() + self.following.pop() + if self.failed: + return + self.match(self.input, 47, self.FOLLOW_47_in_conditional_expression1831) + if self.failed: + return + self.following.append(self.FOLLOW_conditional_expression_in_conditional_expression1833) + self.conditional_expression() + self.following.pop() + if self.failed: + return + if self.backtracking == 0: + self.StorePredicateExpression(e.start.line, e.start.charPositionInLine, e.stop.line, e.stop.charPositionInLine, self.input.toString(e.start,e.stop)) + + + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 51, conditional_expression_StartIndex) + + pass + + return + + # $ANTLR end conditional_expression + + class logical_or_expression_return(object): + def __init__(self): + self.start = None + self.stop = None + + + + # $ANTLR start logical_or_expression + # C.g:431:1: logical_or_expression : logical_and_expression ( '||' logical_and_expression )* ; + def logical_or_expression(self, ): + + retval = self.logical_or_expression_return() + retval.start = self.input.LT(1) + logical_or_expression_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 52): + return retval + + # C.g:432:2: ( logical_and_expression ( '||' logical_and_expression )* ) + # C.g:432:4: logical_and_expression ( '||' logical_and_expression )* + self.following.append(self.FOLLOW_logical_and_expression_in_logical_or_expression1848) + self.logical_and_expression() + self.following.pop() + if self.failed: + return retval + # C.g:432:27: ( '||' logical_and_expression )* + while True: #loop76 + alt76 = 2 + LA76_0 = self.input.LA(1) + + if (LA76_0 == 90) : + alt76 = 1 + + + if alt76 == 1: + # C.g:432:28: '||' logical_and_expression + self.match(self.input, 90, self.FOLLOW_90_in_logical_or_expression1851) + if self.failed: + return retval + self.following.append(self.FOLLOW_logical_and_expression_in_logical_or_expression1853) + self.logical_and_expression() + self.following.pop() + if self.failed: + return retval + + + else: + break #loop76 + + + + + + retval.stop = self.input.LT(-1) + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 52, logical_or_expression_StartIndex) + + pass + + return retval + + # $ANTLR end logical_or_expression + + + # $ANTLR start logical_and_expression + # C.g:435:1: logical_and_expression : inclusive_or_expression ( '&&' inclusive_or_expression )* ; + def logical_and_expression(self, ): + + logical_and_expression_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 53): + return + + # C.g:436:2: ( inclusive_or_expression ( '&&' inclusive_or_expression )* ) + # C.g:436:4: inclusive_or_expression ( '&&' inclusive_or_expression )* + self.following.append(self.FOLLOW_inclusive_or_expression_in_logical_and_expression1866) + self.inclusive_or_expression() + self.following.pop() + if self.failed: + return + # C.g:436:28: ( '&&' inclusive_or_expression )* + while True: #loop77 + alt77 = 2 + LA77_0 = self.input.LA(1) + + if (LA77_0 == 91) : + alt77 = 1 + + + if alt77 == 1: + # C.g:436:29: '&&' inclusive_or_expression + self.match(self.input, 91, self.FOLLOW_91_in_logical_and_expression1869) + if self.failed: + return + self.following.append(self.FOLLOW_inclusive_or_expression_in_logical_and_expression1871) + self.inclusive_or_expression() + self.following.pop() + if self.failed: + return + + + else: + break #loop77 + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 53, logical_and_expression_StartIndex) + + pass + + return + + # $ANTLR end logical_and_expression + + + # $ANTLR start inclusive_or_expression + # C.g:439:1: inclusive_or_expression : exclusive_or_expression ( '|' exclusive_or_expression )* ; + def inclusive_or_expression(self, ): + + inclusive_or_expression_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 54): + return + + # C.g:440:2: ( exclusive_or_expression ( '|' exclusive_or_expression )* ) + # C.g:440:4: exclusive_or_expression ( '|' exclusive_or_expression )* + self.following.append(self.FOLLOW_exclusive_or_expression_in_inclusive_or_expression1884) + self.exclusive_or_expression() + self.following.pop() + if self.failed: + return + # C.g:440:28: ( '|' exclusive_or_expression )* + while True: #loop78 + alt78 = 2 + LA78_0 = self.input.LA(1) + + if (LA78_0 == 92) : + alt78 = 1 + + + if alt78 == 1: + # C.g:440:29: '|' exclusive_or_expression + self.match(self.input, 92, self.FOLLOW_92_in_inclusive_or_expression1887) + if self.failed: + return + self.following.append(self.FOLLOW_exclusive_or_expression_in_inclusive_or_expression1889) + self.exclusive_or_expression() + self.following.pop() + if self.failed: + return + + + else: + break #loop78 + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 54, inclusive_or_expression_StartIndex) + + pass + + return + + # $ANTLR end inclusive_or_expression + + + # $ANTLR start exclusive_or_expression + # C.g:443:1: exclusive_or_expression : and_expression ( '^' and_expression )* ; + def exclusive_or_expression(self, ): + + exclusive_or_expression_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 55): + return + + # C.g:444:2: ( and_expression ( '^' and_expression )* ) + # C.g:444:4: and_expression ( '^' and_expression )* + self.following.append(self.FOLLOW_and_expression_in_exclusive_or_expression1902) + self.and_expression() + self.following.pop() + if self.failed: + return + # C.g:444:19: ( '^' and_expression )* + while True: #loop79 + alt79 = 2 + LA79_0 = self.input.LA(1) + + if (LA79_0 == 93) : + alt79 = 1 + + + if alt79 == 1: + # C.g:444:20: '^' and_expression + self.match(self.input, 93, self.FOLLOW_93_in_exclusive_or_expression1905) + if self.failed: + return + self.following.append(self.FOLLOW_and_expression_in_exclusive_or_expression1907) + self.and_expression() + self.following.pop() + if self.failed: + return + + + else: + break #loop79 + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 55, exclusive_or_expression_StartIndex) + + pass + + return + + # $ANTLR end exclusive_or_expression + + + # $ANTLR start and_expression + # C.g:447:1: and_expression : equality_expression ( '&' equality_expression )* ; + def and_expression(self, ): + + and_expression_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 56): + return + + # C.g:448:2: ( equality_expression ( '&' equality_expression )* ) + # C.g:448:4: equality_expression ( '&' equality_expression )* + self.following.append(self.FOLLOW_equality_expression_in_and_expression1920) + self.equality_expression() + self.following.pop() + if self.failed: + return + # C.g:448:24: ( '&' equality_expression )* + while True: #loop80 + alt80 = 2 + LA80_0 = self.input.LA(1) + + if (LA80_0 == 76) : + alt80 = 1 + + + if alt80 == 1: + # C.g:448:25: '&' equality_expression + self.match(self.input, 76, self.FOLLOW_76_in_and_expression1923) + if self.failed: + return + self.following.append(self.FOLLOW_equality_expression_in_and_expression1925) + self.equality_expression() + self.following.pop() + if self.failed: + return + + + else: + break #loop80 + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 56, and_expression_StartIndex) + + pass + + return + + # $ANTLR end and_expression + + + # $ANTLR start equality_expression + # C.g:450:1: equality_expression : relational_expression ( ( '==' | '!=' ) relational_expression )* ; + def equality_expression(self, ): + + equality_expression_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 57): + return + + # C.g:451:2: ( relational_expression ( ( '==' | '!=' ) relational_expression )* ) + # C.g:451:4: relational_expression ( ( '==' | '!=' ) relational_expression )* + self.following.append(self.FOLLOW_relational_expression_in_equality_expression1937) + self.relational_expression() + self.following.pop() + if self.failed: + return + # C.g:451:26: ( ( '==' | '!=' ) relational_expression )* + while True: #loop81 + alt81 = 2 + LA81_0 = self.input.LA(1) + + if ((94 <= LA81_0 <= 95)) : + alt81 = 1 + + + if alt81 == 1: + # C.g:451:27: ( '==' | '!=' ) relational_expression + if (94 <= self.input.LA(1) <= 95): + self.input.consume(); + self.errorRecovery = False + self.failed = False + + else: + if self.backtracking > 0: + self.failed = True + return + + mse = MismatchedSetException(None, self.input) + self.recoverFromMismatchedSet( + self.input, mse, self.FOLLOW_set_in_equality_expression1940 + ) + raise mse + + + self.following.append(self.FOLLOW_relational_expression_in_equality_expression1946) + self.relational_expression() + self.following.pop() + if self.failed: + return + + + else: + break #loop81 + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 57, equality_expression_StartIndex) + + pass + + return + + # $ANTLR end equality_expression + + + # $ANTLR start relational_expression + # C.g:454:1: relational_expression : shift_expression ( ( '<' | '>' | '<=' | '>=' ) shift_expression )* ; + def relational_expression(self, ): + + relational_expression_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 58): + return + + # C.g:455:2: ( shift_expression ( ( '<' | '>' | '<=' | '>=' ) shift_expression )* ) + # C.g:455:4: shift_expression ( ( '<' | '>' | '<=' | '>=' ) shift_expression )* + self.following.append(self.FOLLOW_shift_expression_in_relational_expression1960) + self.shift_expression() + self.following.pop() + if self.failed: + return + # C.g:455:21: ( ( '<' | '>' | '<=' | '>=' ) shift_expression )* + while True: #loop82 + alt82 = 2 + LA82_0 = self.input.LA(1) + + if ((96 <= LA82_0 <= 99)) : + alt82 = 1 + + + if alt82 == 1: + # C.g:455:22: ( '<' | '>' | '<=' | '>=' ) shift_expression + if (96 <= self.input.LA(1) <= 99): + self.input.consume(); + self.errorRecovery = False + self.failed = False + + else: + if self.backtracking > 0: + self.failed = True + return + + mse = MismatchedSetException(None, self.input) + self.recoverFromMismatchedSet( + self.input, mse, self.FOLLOW_set_in_relational_expression1963 + ) + raise mse + + + self.following.append(self.FOLLOW_shift_expression_in_relational_expression1973) + self.shift_expression() + self.following.pop() + if self.failed: + return + + + else: + break #loop82 + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 58, relational_expression_StartIndex) + + pass + + return + + # $ANTLR end relational_expression + + + # $ANTLR start shift_expression + # C.g:458:1: shift_expression : additive_expression ( ( '<<' | '>>' ) additive_expression )* ; + def shift_expression(self, ): + + shift_expression_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 59): + return + + # C.g:459:2: ( additive_expression ( ( '<<' | '>>' ) additive_expression )* ) + # C.g:459:4: additive_expression ( ( '<<' | '>>' ) additive_expression )* + self.following.append(self.FOLLOW_additive_expression_in_shift_expression1986) + self.additive_expression() + self.following.pop() + if self.failed: + return + # C.g:459:24: ( ( '<<' | '>>' ) additive_expression )* + while True: #loop83 + alt83 = 2 + LA83_0 = self.input.LA(1) + + if ((100 <= LA83_0 <= 101)) : + alt83 = 1 + + + if alt83 == 1: + # C.g:459:25: ( '<<' | '>>' ) additive_expression + if (100 <= self.input.LA(1) <= 101): + self.input.consume(); + self.errorRecovery = False + self.failed = False + + else: + if self.backtracking > 0: + self.failed = True + return + + mse = MismatchedSetException(None, self.input) + self.recoverFromMismatchedSet( + self.input, mse, self.FOLLOW_set_in_shift_expression1989 + ) + raise mse + + + self.following.append(self.FOLLOW_additive_expression_in_shift_expression1995) + self.additive_expression() + self.following.pop() + if self.failed: + return + + + else: + break #loop83 + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 59, shift_expression_StartIndex) + + pass + + return + + # $ANTLR end shift_expression + + + # $ANTLR start statement + # C.g:464:1: statement : ( labeled_statement | compound_statement | expression_statement | selection_statement | iteration_statement | jump_statement | macro_statement | asm2_statement | asm1_statement | asm_statement | declaration ); + def statement(self, ): + + statement_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 60): + return + + # C.g:465:2: ( labeled_statement | compound_statement | expression_statement | selection_statement | iteration_statement | jump_statement | macro_statement | asm2_statement | asm1_statement | asm_statement | declaration ) + alt84 = 11 + LA84 = self.input.LA(1) + if LA84 == IDENTIFIER: + LA84 = self.input.LA(2) + if LA84 == 47: + alt84 = 1 + elif LA84 == 61: + LA84_44 = self.input.LA(3) + + if (self.synpred168()) : + alt84 = 3 + elif (self.synpred172()) : + alt84 = 7 + elif (self.synpred173()) : + alt84 = 8 + elif (True) : + alt84 = 11 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("464:1: statement : ( labeled_statement | compound_statement | expression_statement | selection_statement | iteration_statement | jump_statement | macro_statement | asm2_statement | asm1_statement | asm_statement | declaration );", 84, 44, self.input) + + raise nvae + + elif LA84 == STRING_LITERAL or LA84 == 27 or LA84 == 28 or LA84 == 63 or LA84 == 67 or LA84 == 68 or LA84 == 69 or LA84 == 70 or LA84 == 71 or LA84 == 72 or LA84 == 74 or LA84 == 75 or LA84 == 76 or LA84 == 79 or LA84 == 80 or LA84 == 81 or LA84 == 82 or LA84 == 83 or LA84 == 84 or LA84 == 85 or LA84 == 86 or LA84 == 87 or LA84 == 88 or LA84 == 89 or LA84 == 90 or LA84 == 91 or LA84 == 92 or LA84 == 93 or LA84 == 94 or LA84 == 95 or LA84 == 96 or LA84 == 97 or LA84 == 98 or LA84 == 99 or LA84 == 100 or LA84 == 101: + alt84 = 3 + elif LA84 == 65: + LA84_47 = self.input.LA(3) + + if (self.synpred168()) : + alt84 = 3 + elif (True) : + alt84 = 11 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("464:1: statement : ( labeled_statement | compound_statement | expression_statement | selection_statement | iteration_statement | jump_statement | macro_statement | asm2_statement | asm1_statement | asm_statement | declaration );", 84, 47, self.input) + + raise nvae + + elif LA84 == 25: + LA84_65 = self.input.LA(3) + + if (self.synpred168()) : + alt84 = 3 + elif (True) : + alt84 = 11 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("464:1: statement : ( labeled_statement | compound_statement | expression_statement | selection_statement | iteration_statement | jump_statement | macro_statement | asm2_statement | asm1_statement | asm_statement | declaration );", 84, 65, self.input) + + raise nvae + + elif LA84 == IDENTIFIER: + LA84_67 = self.input.LA(3) + + if (self.synpred168()) : + alt84 = 3 + elif (True) : + alt84 = 11 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("464:1: statement : ( labeled_statement | compound_statement | expression_statement | selection_statement | iteration_statement | jump_statement | macro_statement | asm2_statement | asm1_statement | asm_statement | declaration );", 84, 67, self.input) + + raise nvae + + elif LA84 == 29 or LA84 == 30 or LA84 == 31 or LA84 == 32 or LA84 == 33 or LA84 == 34 or LA84 == 35 or LA84 == 36 or LA84 == 37 or LA84 == 38 or LA84 == 39 or LA84 == 40 or LA84 == 41 or LA84 == 42 or LA84 == 45 or LA84 == 46 or LA84 == 48 or LA84 == 49 or LA84 == 50 or LA84 == 51 or LA84 == 52 or LA84 == 53 or LA84 == 54 or LA84 == 55 or LA84 == 56 or LA84 == 57 or LA84 == 58 or LA84 == 59 or LA84 == 60: + alt84 = 11 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("464:1: statement : ( labeled_statement | compound_statement | expression_statement | selection_statement | iteration_statement | jump_statement | macro_statement | asm2_statement | asm1_statement | asm_statement | declaration );", 84, 1, self.input) + + raise nvae + + elif LA84 == 105 or LA84 == 106: + alt84 = 1 + elif LA84 == 43: + alt84 = 2 + elif LA84 == HEX_LITERAL or LA84 == OCTAL_LITERAL or LA84 == DECIMAL_LITERAL or LA84 == CHARACTER_LITERAL or LA84 == STRING_LITERAL or LA84 == FLOATING_POINT_LITERAL or LA84 == 25 or LA84 == 61 or LA84 == 65 or LA84 == 67 or LA84 == 68 or LA84 == 71 or LA84 == 72 or LA84 == 73 or LA84 == 76 or LA84 == 77 or LA84 == 78: + alt84 = 3 + elif LA84 == 107 or LA84 == 109: + alt84 = 4 + elif LA84 == 110 or LA84 == 111 or LA84 == 112: + alt84 = 5 + elif LA84 == 113 or LA84 == 114 or LA84 == 115 or LA84 == 116: + alt84 = 6 + elif LA84 == 102: + alt84 = 8 + elif LA84 == 103: + alt84 = 9 + elif LA84 == 104: + alt84 = 10 + elif LA84 == 26 or LA84 == 29 or LA84 == 30 or LA84 == 31 or LA84 == 32 or LA84 == 33 or LA84 == 34 or LA84 == 35 or LA84 == 36 or LA84 == 37 or LA84 == 38 or LA84 == 39 or LA84 == 40 or LA84 == 41 or LA84 == 42 or LA84 == 45 or LA84 == 46 or LA84 == 48 or LA84 == 49 or LA84 == 50 or LA84 == 51 or LA84 == 52 or LA84 == 53 or LA84 == 54 or LA84 == 55 or LA84 == 56 or LA84 == 57 or LA84 == 58 or LA84 == 59 or LA84 == 60: + alt84 = 11 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("464:1: statement : ( labeled_statement | compound_statement | expression_statement | selection_statement | iteration_statement | jump_statement | macro_statement | asm2_statement | asm1_statement | asm_statement | declaration );", 84, 0, self.input) + + raise nvae + + if alt84 == 1: + # C.g:465:4: labeled_statement + self.following.append(self.FOLLOW_labeled_statement_in_statement2010) + self.labeled_statement() + self.following.pop() + if self.failed: + return + + + elif alt84 == 2: + # C.g:466:4: compound_statement + self.following.append(self.FOLLOW_compound_statement_in_statement2015) + self.compound_statement() + self.following.pop() + if self.failed: + return + + + elif alt84 == 3: + # C.g:467:4: expression_statement + self.following.append(self.FOLLOW_expression_statement_in_statement2020) + self.expression_statement() + self.following.pop() + if self.failed: + return + + + elif alt84 == 4: + # C.g:468:4: selection_statement + self.following.append(self.FOLLOW_selection_statement_in_statement2025) + self.selection_statement() + self.following.pop() + if self.failed: + return + + + elif alt84 == 5: + # C.g:469:4: iteration_statement + self.following.append(self.FOLLOW_iteration_statement_in_statement2030) + self.iteration_statement() + self.following.pop() + if self.failed: + return + + + elif alt84 == 6: + # C.g:470:4: jump_statement + self.following.append(self.FOLLOW_jump_statement_in_statement2035) + self.jump_statement() + self.following.pop() + if self.failed: + return + + + elif alt84 == 7: + # C.g:471:4: macro_statement + self.following.append(self.FOLLOW_macro_statement_in_statement2040) + self.macro_statement() + self.following.pop() + if self.failed: + return + + + elif alt84 == 8: + # C.g:472:4: asm2_statement + self.following.append(self.FOLLOW_asm2_statement_in_statement2045) + self.asm2_statement() + self.following.pop() + if self.failed: + return + + + elif alt84 == 9: + # C.g:473:4: asm1_statement + self.following.append(self.FOLLOW_asm1_statement_in_statement2050) + self.asm1_statement() + self.following.pop() + if self.failed: + return + + + elif alt84 == 10: + # C.g:474:4: asm_statement + self.following.append(self.FOLLOW_asm_statement_in_statement2055) + self.asm_statement() + self.following.pop() + if self.failed: + return + + + elif alt84 == 11: + # C.g:475:4: declaration + self.following.append(self.FOLLOW_declaration_in_statement2060) + self.declaration() + self.following.pop() + if self.failed: + return + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 60, statement_StartIndex) + + pass + + return + + # $ANTLR end statement + + + # $ANTLR start asm2_statement + # C.g:478:1: asm2_statement : ( '__asm__' )? IDENTIFIER '(' (~ ( ';' ) )* ')' ';' ; + def asm2_statement(self, ): + + asm2_statement_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 61): + return + + # C.g:479:2: ( ( '__asm__' )? IDENTIFIER '(' (~ ( ';' ) )* ')' ';' ) + # C.g:479:4: ( '__asm__' )? IDENTIFIER '(' (~ ( ';' ) )* ')' ';' + # C.g:479:4: ( '__asm__' )? + alt85 = 2 + LA85_0 = self.input.LA(1) + + if (LA85_0 == 102) : + alt85 = 1 + if alt85 == 1: + # C.g:0:0: '__asm__' + self.match(self.input, 102, self.FOLLOW_102_in_asm2_statement2071) + if self.failed: + return + + + + self.match(self.input, IDENTIFIER, self.FOLLOW_IDENTIFIER_in_asm2_statement2074) + if self.failed: + return + self.match(self.input, 61, self.FOLLOW_61_in_asm2_statement2076) + if self.failed: + return + # C.g:479:30: (~ ( ';' ) )* + while True: #loop86 + alt86 = 2 + LA86_0 = self.input.LA(1) + + if (LA86_0 == 62) : + LA86_1 = self.input.LA(2) + + if ((IDENTIFIER <= LA86_1 <= LINE_COMMAND) or (26 <= LA86_1 <= 116)) : + alt86 = 1 + + + elif ((IDENTIFIER <= LA86_0 <= LINE_COMMAND) or (26 <= LA86_0 <= 61) or (63 <= LA86_0 <= 116)) : + alt86 = 1 + + + if alt86 == 1: + # C.g:479:31: ~ ( ';' ) + if (IDENTIFIER <= self.input.LA(1) <= LINE_COMMAND) or (26 <= self.input.LA(1) <= 116): + self.input.consume(); + self.errorRecovery = False + self.failed = False + + else: + if self.backtracking > 0: + self.failed = True + return + + mse = MismatchedSetException(None, self.input) + self.recoverFromMismatchedSet( + self.input, mse, self.FOLLOW_set_in_asm2_statement2079 + ) + raise mse + + + + + else: + break #loop86 + + + self.match(self.input, 62, self.FOLLOW_62_in_asm2_statement2086) + if self.failed: + return + self.match(self.input, 25, self.FOLLOW_25_in_asm2_statement2088) + if self.failed: + return + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 61, asm2_statement_StartIndex) + + pass + + return + + # $ANTLR end asm2_statement + + + # $ANTLR start asm1_statement + # C.g:482:1: asm1_statement : '_asm' '{' (~ ( '}' ) )* '}' ; + def asm1_statement(self, ): + + asm1_statement_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 62): + return + + # C.g:483:2: ( '_asm' '{' (~ ( '}' ) )* '}' ) + # C.g:483:4: '_asm' '{' (~ ( '}' ) )* '}' + self.match(self.input, 103, self.FOLLOW_103_in_asm1_statement2100) + if self.failed: + return + self.match(self.input, 43, self.FOLLOW_43_in_asm1_statement2102) + if self.failed: + return + # C.g:483:15: (~ ( '}' ) )* + while True: #loop87 + alt87 = 2 + LA87_0 = self.input.LA(1) + + if ((IDENTIFIER <= LA87_0 <= 43) or (45 <= LA87_0 <= 116)) : + alt87 = 1 + + + if alt87 == 1: + # C.g:483:16: ~ ( '}' ) + if (IDENTIFIER <= self.input.LA(1) <= 43) or (45 <= self.input.LA(1) <= 116): + self.input.consume(); + self.errorRecovery = False + self.failed = False + + else: + if self.backtracking > 0: + self.failed = True + return + + mse = MismatchedSetException(None, self.input) + self.recoverFromMismatchedSet( + self.input, mse, self.FOLLOW_set_in_asm1_statement2105 + ) + raise mse + + + + + else: + break #loop87 + + + self.match(self.input, 44, self.FOLLOW_44_in_asm1_statement2112) + if self.failed: + return + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 62, asm1_statement_StartIndex) + + pass + + return + + # $ANTLR end asm1_statement + + + # $ANTLR start asm_statement + # C.g:486:1: asm_statement : '__asm' '{' (~ ( '}' ) )* '}' ; + def asm_statement(self, ): + + asm_statement_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 63): + return + + # C.g:487:2: ( '__asm' '{' (~ ( '}' ) )* '}' ) + # C.g:487:4: '__asm' '{' (~ ( '}' ) )* '}' + self.match(self.input, 104, self.FOLLOW_104_in_asm_statement2123) + if self.failed: + return + self.match(self.input, 43, self.FOLLOW_43_in_asm_statement2125) + if self.failed: + return + # C.g:487:16: (~ ( '}' ) )* + while True: #loop88 + alt88 = 2 + LA88_0 = self.input.LA(1) + + if ((IDENTIFIER <= LA88_0 <= 43) or (45 <= LA88_0 <= 116)) : + alt88 = 1 + + + if alt88 == 1: + # C.g:487:17: ~ ( '}' ) + if (IDENTIFIER <= self.input.LA(1) <= 43) or (45 <= self.input.LA(1) <= 116): + self.input.consume(); + self.errorRecovery = False + self.failed = False + + else: + if self.backtracking > 0: + self.failed = True + return + + mse = MismatchedSetException(None, self.input) + self.recoverFromMismatchedSet( + self.input, mse, self.FOLLOW_set_in_asm_statement2128 + ) + raise mse + + + + + else: + break #loop88 + + + self.match(self.input, 44, self.FOLLOW_44_in_asm_statement2135) + if self.failed: + return + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 63, asm_statement_StartIndex) + + pass + + return + + # $ANTLR end asm_statement + + + # $ANTLR start macro_statement + # C.g:490:1: macro_statement : IDENTIFIER '(' ( declaration )* ( statement_list )? ( expression )? ')' ; + def macro_statement(self, ): + + macro_statement_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 64): + return + + # C.g:491:2: ( IDENTIFIER '(' ( declaration )* ( statement_list )? ( expression )? ')' ) + # C.g:491:4: IDENTIFIER '(' ( declaration )* ( statement_list )? ( expression )? ')' + self.match(self.input, IDENTIFIER, self.FOLLOW_IDENTIFIER_in_macro_statement2147) + if self.failed: + return + self.match(self.input, 61, self.FOLLOW_61_in_macro_statement2149) + if self.failed: + return + # C.g:491:19: ( declaration )* + while True: #loop89 + alt89 = 2 + LA89 = self.input.LA(1) + if LA89 == IDENTIFIER: + LA89 = self.input.LA(2) + if LA89 == 61: + LA89_45 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 65: + LA89_48 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 25: + LA89_66 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == IDENTIFIER: + LA89_69 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 58: + LA89_70 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 59: + LA89_71 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 60: + LA89_72 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 29 or LA89 == 30 or LA89 == 31 or LA89 == 32 or LA89 == 33: + LA89_73 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 34: + LA89_74 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 35: + LA89_75 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 36: + LA89_76 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 37: + LA89_77 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 38: + LA89_78 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 39: + LA89_79 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 40: + LA89_80 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 41: + LA89_81 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 42: + LA89_82 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 45 or LA89 == 46: + LA89_83 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 48: + LA89_84 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 49 or LA89 == 50 or LA89 == 51 or LA89 == 52 or LA89 == 53 or LA89 == 54 or LA89 == 55 or LA89 == 56 or LA89 == 57: + LA89_85 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + + elif LA89 == 26: + LA89 = self.input.LA(2) + if LA89 == 29 or LA89 == 30 or LA89 == 31 or LA89 == 32 or LA89 == 33: + LA89_87 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 34: + LA89_88 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 35: + LA89_89 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 36: + LA89_90 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 37: + LA89_91 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 38: + LA89_92 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 39: + LA89_93 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 40: + LA89_94 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 41: + LA89_95 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 42: + LA89_96 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 45 or LA89 == 46: + LA89_97 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 48: + LA89_98 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == IDENTIFIER: + LA89_99 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 58: + LA89_100 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 65: + LA89_101 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 59: + LA89_102 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 60: + LA89_103 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 49 or LA89 == 50 or LA89 == 51 or LA89 == 52 or LA89 == 53 or LA89 == 54 or LA89 == 55 or LA89 == 56 or LA89 == 57: + LA89_104 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 61: + LA89_105 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + + elif LA89 == 29 or LA89 == 30 or LA89 == 31 or LA89 == 32 or LA89 == 33: + LA89 = self.input.LA(2) + if LA89 == 65: + LA89_106 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 58: + LA89_107 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 59: + LA89_108 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 60: + LA89_109 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == IDENTIFIER: + LA89_110 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 61: + LA89_111 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 25: + LA89_112 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 29 or LA89 == 30 or LA89 == 31 or LA89 == 32 or LA89 == 33: + LA89_113 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 34: + LA89_114 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 35: + LA89_115 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 36: + LA89_116 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 37: + LA89_117 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 38: + LA89_118 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 39: + LA89_119 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 40: + LA89_120 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 41: + LA89_121 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 42: + LA89_122 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 45 or LA89 == 46: + LA89_123 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 48: + LA89_124 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 49 or LA89 == 50 or LA89 == 51 or LA89 == 52 or LA89 == 53 or LA89 == 54 or LA89 == 55 or LA89 == 56 or LA89 == 57: + LA89_125 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + + elif LA89 == 34: + LA89 = self.input.LA(2) + if LA89 == 65: + LA89_126 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 58: + LA89_127 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 59: + LA89_128 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 60: + LA89_129 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == IDENTIFIER: + LA89_130 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 61: + LA89_131 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 25: + LA89_132 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 29 or LA89 == 30 or LA89 == 31 or LA89 == 32 or LA89 == 33: + LA89_133 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 34: + LA89_134 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 35: + LA89_135 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 36: + LA89_136 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 37: + LA89_137 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 38: + LA89_138 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 39: + LA89_139 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 40: + LA89_140 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 41: + LA89_141 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 42: + LA89_142 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 45 or LA89 == 46: + LA89_143 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 48: + LA89_144 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 49 or LA89 == 50 or LA89 == 51 or LA89 == 52 or LA89 == 53 or LA89 == 54 or LA89 == 55 or LA89 == 56 or LA89 == 57: + LA89_145 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + + elif LA89 == 35: + LA89 = self.input.LA(2) + if LA89 == 65: + LA89_146 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 58: + LA89_147 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 59: + LA89_148 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 60: + LA89_149 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == IDENTIFIER: + LA89_150 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 61: + LA89_151 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 25: + LA89_152 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 29 or LA89 == 30 or LA89 == 31 or LA89 == 32 or LA89 == 33: + LA89_153 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 34: + LA89_154 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 35: + LA89_155 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 36: + LA89_156 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 37: + LA89_157 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 38: + LA89_158 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 39: + LA89_159 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 40: + LA89_160 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 41: + LA89_161 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 42: + LA89_162 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 45 or LA89 == 46: + LA89_163 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 48: + LA89_164 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 49 or LA89 == 50 or LA89 == 51 or LA89 == 52 or LA89 == 53 or LA89 == 54 or LA89 == 55 or LA89 == 56 or LA89 == 57: + LA89_165 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + + elif LA89 == 36: + LA89 = self.input.LA(2) + if LA89 == 65: + LA89_166 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 58: + LA89_167 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 59: + LA89_168 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 60: + LA89_169 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == IDENTIFIER: + LA89_170 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 61: + LA89_171 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 25: + LA89_172 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 29 or LA89 == 30 or LA89 == 31 or LA89 == 32 or LA89 == 33: + LA89_173 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 34: + LA89_174 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 35: + LA89_175 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 36: + LA89_176 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 37: + LA89_177 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 38: + LA89_178 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 39: + LA89_179 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 40: + LA89_180 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 41: + LA89_181 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 42: + LA89_182 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 45 or LA89 == 46: + LA89_183 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 48: + LA89_184 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 49 or LA89 == 50 or LA89 == 51 or LA89 == 52 or LA89 == 53 or LA89 == 54 or LA89 == 55 or LA89 == 56 or LA89 == 57: + LA89_185 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + + elif LA89 == 37: + LA89 = self.input.LA(2) + if LA89 == 65: + LA89_186 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 58: + LA89_187 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 59: + LA89_188 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 60: + LA89_189 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == IDENTIFIER: + LA89_190 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 61: + LA89_191 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 25: + LA89_192 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 29 or LA89 == 30 or LA89 == 31 or LA89 == 32 or LA89 == 33: + LA89_193 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 34: + LA89_194 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 35: + LA89_195 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 36: + LA89_196 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 37: + LA89_197 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 38: + LA89_198 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 39: + LA89_199 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 40: + LA89_200 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 41: + LA89_201 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 42: + LA89_202 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 45 or LA89 == 46: + LA89_203 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 48: + LA89_204 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 49 or LA89 == 50 or LA89 == 51 or LA89 == 52 or LA89 == 53 or LA89 == 54 or LA89 == 55 or LA89 == 56 or LA89 == 57: + LA89_205 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + + elif LA89 == 38: + LA89 = self.input.LA(2) + if LA89 == 65: + LA89_206 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 58: + LA89_207 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 59: + LA89_208 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 60: + LA89_209 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == IDENTIFIER: + LA89_210 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 61: + LA89_211 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 25: + LA89_212 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 29 or LA89 == 30 or LA89 == 31 or LA89 == 32 or LA89 == 33: + LA89_213 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 34: + LA89_214 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 35: + LA89_215 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 36: + LA89_216 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 37: + LA89_217 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 38: + LA89_218 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 39: + LA89_219 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 40: + LA89_220 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 41: + LA89_221 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 42: + LA89_222 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 45 or LA89 == 46: + LA89_223 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 48: + LA89_224 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 49 or LA89 == 50 or LA89 == 51 or LA89 == 52 or LA89 == 53 or LA89 == 54 or LA89 == 55 or LA89 == 56 or LA89 == 57: + LA89_225 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + + elif LA89 == 39: + LA89 = self.input.LA(2) + if LA89 == 65: + LA89_226 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 58: + LA89_227 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 59: + LA89_228 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 60: + LA89_229 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == IDENTIFIER: + LA89_230 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 61: + LA89_231 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 25: + LA89_232 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 29 or LA89 == 30 or LA89 == 31 or LA89 == 32 or LA89 == 33: + LA89_233 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 34: + LA89_234 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 35: + LA89_235 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 36: + LA89_236 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 37: + LA89_237 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 38: + LA89_238 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 39: + LA89_239 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 40: + LA89_240 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 41: + LA89_241 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 42: + LA89_242 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 45 or LA89 == 46: + LA89_243 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 48: + LA89_244 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 49 or LA89 == 50 or LA89 == 51 or LA89 == 52 or LA89 == 53 or LA89 == 54 or LA89 == 55 or LA89 == 56 or LA89 == 57: + LA89_245 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + + elif LA89 == 40: + LA89 = self.input.LA(2) + if LA89 == 65: + LA89_246 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 58: + LA89_247 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 59: + LA89_248 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 60: + LA89_249 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == IDENTIFIER: + LA89_250 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 61: + LA89_251 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 25: + LA89_252 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 29 or LA89 == 30 or LA89 == 31 or LA89 == 32 or LA89 == 33: + LA89_253 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 34: + LA89_254 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 35: + LA89_255 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 36: + LA89_256 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 37: + LA89_257 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 38: + LA89_258 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 39: + LA89_259 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 40: + LA89_260 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 41: + LA89_261 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 42: + LA89_262 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 45 or LA89 == 46: + LA89_263 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 48: + LA89_264 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 49 or LA89 == 50 or LA89 == 51 or LA89 == 52 or LA89 == 53 or LA89 == 54 or LA89 == 55 or LA89 == 56 or LA89 == 57: + LA89_265 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + + elif LA89 == 41: + LA89 = self.input.LA(2) + if LA89 == 65: + LA89_266 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 58: + LA89_267 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 59: + LA89_268 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 60: + LA89_269 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == IDENTIFIER: + LA89_270 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 61: + LA89_271 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 25: + LA89_272 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 29 or LA89 == 30 or LA89 == 31 or LA89 == 32 or LA89 == 33: + LA89_273 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 34: + LA89_274 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 35: + LA89_275 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 36: + LA89_276 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 37: + LA89_277 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 38: + LA89_278 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 39: + LA89_279 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 40: + LA89_280 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 41: + LA89_281 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 42: + LA89_282 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 45 or LA89 == 46: + LA89_283 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 48: + LA89_284 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 49 or LA89 == 50 or LA89 == 51 or LA89 == 52 or LA89 == 53 or LA89 == 54 or LA89 == 55 or LA89 == 56 or LA89 == 57: + LA89_285 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + + elif LA89 == 42: + LA89 = self.input.LA(2) + if LA89 == 65: + LA89_286 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 58: + LA89_287 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 59: + LA89_288 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 60: + LA89_289 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == IDENTIFIER: + LA89_290 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 61: + LA89_291 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 25: + LA89_292 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 29 or LA89 == 30 or LA89 == 31 or LA89 == 32 or LA89 == 33: + LA89_293 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 34: + LA89_294 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 35: + LA89_295 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 36: + LA89_296 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 37: + LA89_297 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 38: + LA89_298 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 39: + LA89_299 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 40: + LA89_300 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 41: + LA89_301 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 42: + LA89_302 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 45 or LA89 == 46: + LA89_303 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 48: + LA89_304 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 49 or LA89 == 50 or LA89 == 51 or LA89 == 52 or LA89 == 53 or LA89 == 54 or LA89 == 55 or LA89 == 56 or LA89 == 57: + LA89_305 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + + elif LA89 == 45 or LA89 == 46: + LA89_40 = self.input.LA(2) + + if (LA89_40 == IDENTIFIER) : + LA89_306 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif (LA89_40 == 43) : + LA89_307 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + + + elif LA89 == 48: + LA89_41 = self.input.LA(2) + + if (LA89_41 == IDENTIFIER) : + LA89_308 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif (LA89_41 == 43) : + LA89_309 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + + + elif LA89 == 49 or LA89 == 50 or LA89 == 51 or LA89 == 52 or LA89 == 53 or LA89 == 54 or LA89 == 55 or LA89 == 56 or LA89 == 57 or LA89 == 58 or LA89 == 59 or LA89 == 60: + LA89 = self.input.LA(2) + if LA89 == 65: + LA89_310 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 58: + LA89_311 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 59: + LA89_312 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 60: + LA89_313 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == IDENTIFIER: + LA89_314 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 61: + LA89_315 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 25: + LA89_316 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 29 or LA89 == 30 or LA89 == 31 or LA89 == 32 or LA89 == 33: + LA89_317 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 34: + LA89_318 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 35: + LA89_319 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 36: + LA89_320 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 37: + LA89_321 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 38: + LA89_322 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 39: + LA89_323 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 40: + LA89_324 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 41: + LA89_325 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 42: + LA89_326 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 45 or LA89 == 46: + LA89_327 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 48: + LA89_328 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + elif LA89 == 49 or LA89 == 50 or LA89 == 51 or LA89 == 52 or LA89 == 53 or LA89 == 54 or LA89 == 55 or LA89 == 56 or LA89 == 57: + LA89_329 = self.input.LA(3) + + if (self.synpred180()) : + alt89 = 1 + + + + + if alt89 == 1: + # C.g:0:0: declaration + self.following.append(self.FOLLOW_declaration_in_macro_statement2151) + self.declaration() + self.following.pop() + if self.failed: + return + + + else: + break #loop89 + + + # C.g:491:33: ( statement_list )? + alt90 = 2 + LA90 = self.input.LA(1) + if LA90 == IDENTIFIER: + LA90 = self.input.LA(2) + if LA90 == 61: + LA90_44 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 25 or LA90 == 29 or LA90 == 30 or LA90 == 31 or LA90 == 32 or LA90 == 33 or LA90 == 34 or LA90 == 35 or LA90 == 36 or LA90 == 37 or LA90 == 38 or LA90 == 39 or LA90 == 40 or LA90 == 41 or LA90 == 42 or LA90 == 45 or LA90 == 46 or LA90 == 47 or LA90 == 48 or LA90 == 49 or LA90 == 50 or LA90 == 51 or LA90 == 52 or LA90 == 53 or LA90 == 54 or LA90 == 55 or LA90 == 56 or LA90 == 57 or LA90 == 58 or LA90 == 59 or LA90 == 60: + alt90 = 1 + elif LA90 == STRING_LITERAL: + LA90_46 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == IDENTIFIER: + LA90_47 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 63: + LA90_48 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 74: + LA90_49 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 65: + LA90_50 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 75: + LA90_51 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 71: + LA90_52 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 72: + LA90_53 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 28 or LA90 == 79 or LA90 == 80 or LA90 == 81 or LA90 == 82 or LA90 == 83 or LA90 == 84 or LA90 == 85 or LA90 == 86 or LA90 == 87 or LA90 == 88: + LA90_54 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 69: + LA90_72 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 70: + LA90_73 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 67: + LA90_74 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 68: + LA90_75 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 100 or LA90 == 101: + LA90_76 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 96 or LA90 == 97 or LA90 == 98 or LA90 == 99: + LA90_77 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 94 or LA90 == 95: + LA90_78 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 76: + LA90_79 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 93: + LA90_80 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 92: + LA90_81 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 91: + LA90_82 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 90: + LA90_83 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 89: + LA90_84 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 27: + LA90_85 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 25 or LA90 == 26 or LA90 == 29 or LA90 == 30 or LA90 == 31 or LA90 == 32 or LA90 == 33 or LA90 == 34 or LA90 == 35 or LA90 == 36 or LA90 == 37 or LA90 == 38 or LA90 == 39 or LA90 == 40 or LA90 == 41 or LA90 == 42 or LA90 == 43 or LA90 == 45 or LA90 == 46 or LA90 == 48 or LA90 == 49 or LA90 == 50 or LA90 == 51 or LA90 == 52 or LA90 == 53 or LA90 == 54 or LA90 == 55 or LA90 == 56 or LA90 == 57 or LA90 == 58 or LA90 == 59 or LA90 == 60 or LA90 == 102 or LA90 == 103 or LA90 == 104 or LA90 == 105 or LA90 == 106 or LA90 == 107 or LA90 == 109 or LA90 == 110 or LA90 == 111 or LA90 == 112 or LA90 == 113 or LA90 == 114 or LA90 == 115 or LA90 == 116: + alt90 = 1 + elif LA90 == HEX_LITERAL: + LA90 = self.input.LA(2) + if LA90 == 63: + LA90_87 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 61: + LA90_88 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 74: + LA90_89 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 65: + LA90_90 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 75: + LA90_91 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 71: + LA90_92 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 72: + LA90_93 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 69: + LA90_94 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 70: + LA90_95 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 67: + LA90_96 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 68: + LA90_97 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 100 or LA90 == 101: + LA90_98 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 96 or LA90 == 97 or LA90 == 98 or LA90 == 99: + LA90_99 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 94 or LA90 == 95: + LA90_100 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 76: + LA90_101 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 93: + LA90_102 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 92: + LA90_103 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 91: + LA90_104 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 90: + LA90_105 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 89: + LA90_106 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 27: + LA90_107 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 25: + alt90 = 1 + elif LA90 == 28 or LA90 == 79 or LA90 == 80 or LA90 == 81 or LA90 == 82 or LA90 == 83 or LA90 == 84 or LA90 == 85 or LA90 == 86 or LA90 == 87 or LA90 == 88: + LA90_110 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == OCTAL_LITERAL: + LA90 = self.input.LA(2) + if LA90 == 63: + LA90_111 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 61: + LA90_112 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 74: + LA90_113 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 65: + LA90_114 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 75: + LA90_115 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 71: + LA90_116 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 72: + LA90_117 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 28 or LA90 == 79 or LA90 == 80 or LA90 == 81 or LA90 == 82 or LA90 == 83 or LA90 == 84 or LA90 == 85 or LA90 == 86 or LA90 == 87 or LA90 == 88: + LA90_118 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 69: + LA90_119 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 70: + LA90_120 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 67: + LA90_121 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 68: + LA90_122 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 100 or LA90 == 101: + LA90_123 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 96 or LA90 == 97 or LA90 == 98 or LA90 == 99: + LA90_124 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 94 or LA90 == 95: + LA90_125 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 76: + LA90_126 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 93: + LA90_127 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 92: + LA90_128 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 91: + LA90_129 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 90: + LA90_130 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 89: + LA90_131 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 27: + LA90_132 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 25: + alt90 = 1 + elif LA90 == DECIMAL_LITERAL: + LA90 = self.input.LA(2) + if LA90 == 63: + LA90_135 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 61: + LA90_136 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 74: + LA90_137 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 65: + LA90_138 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 75: + LA90_139 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 71: + LA90_140 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 72: + LA90_141 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 28 or LA90 == 79 or LA90 == 80 or LA90 == 81 or LA90 == 82 or LA90 == 83 or LA90 == 84 or LA90 == 85 or LA90 == 86 or LA90 == 87 or LA90 == 88: + LA90_142 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 69: + LA90_143 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 70: + LA90_144 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 67: + LA90_145 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 68: + LA90_146 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 100 or LA90 == 101: + LA90_147 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 96 or LA90 == 97 or LA90 == 98 or LA90 == 99: + LA90_148 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 94 or LA90 == 95: + LA90_149 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 76: + LA90_150 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 93: + LA90_151 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 92: + LA90_152 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 91: + LA90_153 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 90: + LA90_154 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 89: + LA90_155 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 27: + LA90_156 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 25: + alt90 = 1 + elif LA90 == CHARACTER_LITERAL: + LA90 = self.input.LA(2) + if LA90 == 63: + LA90_159 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 61: + LA90_160 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 74: + LA90_161 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 65: + LA90_162 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 75: + LA90_163 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 71: + LA90_164 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 72: + LA90_165 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 28 or LA90 == 79 or LA90 == 80 or LA90 == 81 or LA90 == 82 or LA90 == 83 or LA90 == 84 or LA90 == 85 or LA90 == 86 or LA90 == 87 or LA90 == 88: + LA90_166 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 69: + LA90_167 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 70: + LA90_168 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 67: + LA90_169 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 68: + LA90_170 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 100 or LA90 == 101: + LA90_171 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 96 or LA90 == 97 or LA90 == 98 or LA90 == 99: + LA90_172 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 94 or LA90 == 95: + LA90_173 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 76: + LA90_174 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 93: + LA90_175 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 92: + LA90_176 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 91: + LA90_177 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 90: + LA90_178 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 89: + LA90_179 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 27: + LA90_180 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 25: + alt90 = 1 + elif LA90 == STRING_LITERAL: + LA90 = self.input.LA(2) + if LA90 == IDENTIFIER: + LA90_183 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 63: + LA90_184 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 61: + LA90_185 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 74: + LA90_186 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 65: + LA90_187 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 75: + LA90_188 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 71: + LA90_189 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 72: + LA90_190 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 69: + LA90_191 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 70: + LA90_192 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 67: + LA90_193 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 68: + LA90_194 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 100 or LA90 == 101: + LA90_195 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 96 or LA90 == 97 or LA90 == 98 or LA90 == 99: + LA90_196 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 94 or LA90 == 95: + LA90_197 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 76: + LA90_198 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 93: + LA90_199 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 92: + LA90_200 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 91: + LA90_201 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 90: + LA90_202 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 89: + LA90_203 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 27: + LA90_204 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 25: + alt90 = 1 + elif LA90 == STRING_LITERAL: + LA90_206 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 28 or LA90 == 79 or LA90 == 80 or LA90 == 81 or LA90 == 82 or LA90 == 83 or LA90 == 84 or LA90 == 85 or LA90 == 86 or LA90 == 87 or LA90 == 88: + LA90_207 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == FLOATING_POINT_LITERAL: + LA90 = self.input.LA(2) + if LA90 == 63: + LA90_209 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 61: + LA90_210 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 74: + LA90_211 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 65: + LA90_212 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 75: + LA90_213 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 71: + LA90_214 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 72: + LA90_215 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 69: + LA90_216 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 70: + LA90_217 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 67: + LA90_218 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 68: + LA90_219 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 100 or LA90 == 101: + LA90_220 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 96 or LA90 == 97 or LA90 == 98 or LA90 == 99: + LA90_221 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 94 or LA90 == 95: + LA90_222 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 76: + LA90_223 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 93: + LA90_224 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 92: + LA90_225 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 91: + LA90_226 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 90: + LA90_227 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 89: + LA90_228 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 27: + LA90_229 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 25: + alt90 = 1 + elif LA90 == 28 or LA90 == 79 or LA90 == 80 or LA90 == 81 or LA90 == 82 or LA90 == 83 or LA90 == 84 or LA90 == 85 or LA90 == 86 or LA90 == 87 or LA90 == 88: + LA90_231 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 61: + LA90 = self.input.LA(2) + if LA90 == IDENTIFIER: + LA90_233 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == HEX_LITERAL: + LA90_234 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == OCTAL_LITERAL: + LA90_235 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == DECIMAL_LITERAL: + LA90_236 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == CHARACTER_LITERAL: + LA90_237 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == STRING_LITERAL: + LA90_238 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == FLOATING_POINT_LITERAL: + LA90_239 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 61: + LA90_240 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 71: + LA90_241 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 72: + LA90_242 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 65 or LA90 == 67 or LA90 == 68 or LA90 == 76 or LA90 == 77 or LA90 == 78: + LA90_243 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 73: + LA90_244 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 49 or LA90 == 50 or LA90 == 51 or LA90 == 52 or LA90 == 53 or LA90 == 54 or LA90 == 55 or LA90 == 56 or LA90 == 57 or LA90 == 58 or LA90 == 59 or LA90 == 60: + LA90_245 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 34: + LA90_246 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 35: + LA90_247 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 36: + LA90_248 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 37: + LA90_249 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 38: + LA90_250 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 39: + LA90_251 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 40: + LA90_252 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 41: + LA90_253 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 42: + LA90_254 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 45 or LA90 == 46: + LA90_255 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 48: + LA90_256 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 71: + LA90 = self.input.LA(2) + if LA90 == IDENTIFIER: + LA90_257 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == HEX_LITERAL: + LA90_258 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == OCTAL_LITERAL: + LA90_259 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == DECIMAL_LITERAL: + LA90_260 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == CHARACTER_LITERAL: + LA90_261 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == STRING_LITERAL: + LA90_262 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == FLOATING_POINT_LITERAL: + LA90_263 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 61: + LA90_264 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 71: + LA90_265 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 72: + LA90_266 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 65 or LA90 == 67 or LA90 == 68 or LA90 == 76 or LA90 == 77 or LA90 == 78: + LA90_267 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 73: + LA90_268 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 72: + LA90 = self.input.LA(2) + if LA90 == IDENTIFIER: + LA90_269 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == HEX_LITERAL: + LA90_270 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == OCTAL_LITERAL: + LA90_271 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == DECIMAL_LITERAL: + LA90_272 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == CHARACTER_LITERAL: + LA90_273 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == STRING_LITERAL: + LA90_274 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == FLOATING_POINT_LITERAL: + LA90_275 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 61: + LA90_276 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 71: + LA90_277 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 72: + LA90_278 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 65 or LA90 == 67 or LA90 == 68 or LA90 == 76 or LA90 == 77 or LA90 == 78: + LA90_279 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 73: + LA90_280 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 65 or LA90 == 67 or LA90 == 68 or LA90 == 76 or LA90 == 77 or LA90 == 78: + LA90 = self.input.LA(2) + if LA90 == 61: + LA90_281 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == IDENTIFIER: + LA90_282 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == HEX_LITERAL: + LA90_283 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == OCTAL_LITERAL: + LA90_284 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == DECIMAL_LITERAL: + LA90_285 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == CHARACTER_LITERAL: + LA90_286 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == STRING_LITERAL: + LA90_287 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == FLOATING_POINT_LITERAL: + LA90_288 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 71: + LA90_289 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 72: + LA90_290 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 65 or LA90 == 67 or LA90 == 68 or LA90 == 76 or LA90 == 77 or LA90 == 78: + LA90_291 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 73: + LA90_292 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 73: + LA90 = self.input.LA(2) + if LA90 == 61: + LA90_293 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == IDENTIFIER: + LA90_294 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == HEX_LITERAL: + LA90_295 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == OCTAL_LITERAL: + LA90_296 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == DECIMAL_LITERAL: + LA90_297 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == CHARACTER_LITERAL: + LA90_298 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == STRING_LITERAL: + LA90_299 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == FLOATING_POINT_LITERAL: + LA90_300 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 71: + LA90_301 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 72: + LA90_302 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 65 or LA90 == 67 or LA90 == 68 or LA90 == 76 or LA90 == 77 or LA90 == 78: + LA90_303 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + elif LA90 == 73: + LA90_304 = self.input.LA(3) + + if (self.synpred181()) : + alt90 = 1 + if alt90 == 1: + # C.g:0:0: statement_list + self.following.append(self.FOLLOW_statement_list_in_macro_statement2155) + self.statement_list() + self.following.pop() + if self.failed: + return + + + + # C.g:491:49: ( expression )? + alt91 = 2 + LA91_0 = self.input.LA(1) + + if ((IDENTIFIER <= LA91_0 <= FLOATING_POINT_LITERAL) or LA91_0 == 61 or LA91_0 == 65 or (67 <= LA91_0 <= 68) or (71 <= LA91_0 <= 73) or (76 <= LA91_0 <= 78)) : + alt91 = 1 + if alt91 == 1: + # C.g:0:0: expression + self.following.append(self.FOLLOW_expression_in_macro_statement2158) + self.expression() + self.following.pop() + if self.failed: + return + + + + self.match(self.input, 62, self.FOLLOW_62_in_macro_statement2161) + if self.failed: + return + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 64, macro_statement_StartIndex) + + pass + + return + + # $ANTLR end macro_statement + + + # $ANTLR start labeled_statement + # C.g:494:1: labeled_statement : ( IDENTIFIER ':' statement | 'case' constant_expression ':' statement | 'default' ':' statement ); + def labeled_statement(self, ): + + labeled_statement_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 65): + return + + # C.g:495:2: ( IDENTIFIER ':' statement | 'case' constant_expression ':' statement | 'default' ':' statement ) + alt92 = 3 + LA92 = self.input.LA(1) + if LA92 == IDENTIFIER: + alt92 = 1 + elif LA92 == 105: + alt92 = 2 + elif LA92 == 106: + alt92 = 3 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("494:1: labeled_statement : ( IDENTIFIER ':' statement | 'case' constant_expression ':' statement | 'default' ':' statement );", 92, 0, self.input) + + raise nvae + + if alt92 == 1: + # C.g:495:4: IDENTIFIER ':' statement + self.match(self.input, IDENTIFIER, self.FOLLOW_IDENTIFIER_in_labeled_statement2173) + if self.failed: + return + self.match(self.input, 47, self.FOLLOW_47_in_labeled_statement2175) + if self.failed: + return + self.following.append(self.FOLLOW_statement_in_labeled_statement2177) + self.statement() + self.following.pop() + if self.failed: + return + + + elif alt92 == 2: + # C.g:496:4: 'case' constant_expression ':' statement + self.match(self.input, 105, self.FOLLOW_105_in_labeled_statement2182) + if self.failed: + return + self.following.append(self.FOLLOW_constant_expression_in_labeled_statement2184) + self.constant_expression() + self.following.pop() + if self.failed: + return + self.match(self.input, 47, self.FOLLOW_47_in_labeled_statement2186) + if self.failed: + return + self.following.append(self.FOLLOW_statement_in_labeled_statement2188) + self.statement() + self.following.pop() + if self.failed: + return + + + elif alt92 == 3: + # C.g:497:4: 'default' ':' statement + self.match(self.input, 106, self.FOLLOW_106_in_labeled_statement2193) + if self.failed: + return + self.match(self.input, 47, self.FOLLOW_47_in_labeled_statement2195) + if self.failed: + return + self.following.append(self.FOLLOW_statement_in_labeled_statement2197) + self.statement() + self.following.pop() + if self.failed: + return + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 65, labeled_statement_StartIndex) + + pass + + return + + # $ANTLR end labeled_statement + + class compound_statement_return(object): + def __init__(self): + self.start = None + self.stop = None + + + + # $ANTLR start compound_statement + # C.g:500:1: compound_statement : '{' ( declaration )* ( statement_list )? '}' ; + def compound_statement(self, ): + + retval = self.compound_statement_return() + retval.start = self.input.LT(1) + compound_statement_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 66): + return retval + + # C.g:501:2: ( '{' ( declaration )* ( statement_list )? '}' ) + # C.g:501:4: '{' ( declaration )* ( statement_list )? '}' + self.match(self.input, 43, self.FOLLOW_43_in_compound_statement2208) + if self.failed: + return retval + # C.g:501:8: ( declaration )* + while True: #loop93 + alt93 = 2 + LA93 = self.input.LA(1) + if LA93 == IDENTIFIER: + LA93 = self.input.LA(2) + if LA93 == 61: + LA93_44 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 65: + LA93_48 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 25: + LA93_67 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == IDENTIFIER: + LA93_69 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 58: + LA93_70 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 59: + LA93_71 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 60: + LA93_72 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 29 or LA93 == 30 or LA93 == 31 or LA93 == 32 or LA93 == 33: + LA93_73 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 34: + LA93_74 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 35: + LA93_75 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 36: + LA93_76 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 37: + LA93_77 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 38: + LA93_78 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 39: + LA93_79 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 40: + LA93_80 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 41: + LA93_81 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 42: + LA93_82 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 45 or LA93 == 46: + LA93_83 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 48: + LA93_84 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 49 or LA93 == 50 or LA93 == 51 or LA93 == 52 or LA93 == 53 or LA93 == 54 or LA93 == 55 or LA93 == 56 or LA93 == 57: + LA93_85 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + + elif LA93 == 26: + LA93 = self.input.LA(2) + if LA93 == 29 or LA93 == 30 or LA93 == 31 or LA93 == 32 or LA93 == 33: + LA93_86 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 34: + LA93_87 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 35: + LA93_88 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 36: + LA93_89 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 37: + LA93_90 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 38: + LA93_91 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 39: + LA93_92 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 40: + LA93_93 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 41: + LA93_94 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 42: + LA93_95 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 45 or LA93 == 46: + LA93_96 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 48: + LA93_97 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == IDENTIFIER: + LA93_98 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 58: + LA93_99 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 65: + LA93_100 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 59: + LA93_101 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 60: + LA93_102 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 49 or LA93 == 50 or LA93 == 51 or LA93 == 52 or LA93 == 53 or LA93 == 54 or LA93 == 55 or LA93 == 56 or LA93 == 57: + LA93_103 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 61: + LA93_104 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + + elif LA93 == 29 or LA93 == 30 or LA93 == 31 or LA93 == 32 or LA93 == 33: + LA93 = self.input.LA(2) + if LA93 == 65: + LA93_105 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 58: + LA93_106 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 59: + LA93_107 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 60: + LA93_108 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == IDENTIFIER: + LA93_109 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 61: + LA93_110 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 25: + LA93_111 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 29 or LA93 == 30 or LA93 == 31 or LA93 == 32 or LA93 == 33: + LA93_112 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 34: + LA93_113 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 35: + LA93_114 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 36: + LA93_115 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 37: + LA93_116 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 38: + LA93_117 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 39: + LA93_118 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 40: + LA93_119 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 41: + LA93_120 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 42: + LA93_121 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 45 or LA93 == 46: + LA93_122 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 48: + LA93_123 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 49 or LA93 == 50 or LA93 == 51 or LA93 == 52 or LA93 == 53 or LA93 == 54 or LA93 == 55 or LA93 == 56 or LA93 == 57: + LA93_124 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + + elif LA93 == 34: + LA93 = self.input.LA(2) + if LA93 == 65: + LA93_125 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 58: + LA93_126 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 59: + LA93_127 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 60: + LA93_128 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == IDENTIFIER: + LA93_129 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 61: + LA93_130 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 25: + LA93_131 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 29 or LA93 == 30 or LA93 == 31 or LA93 == 32 or LA93 == 33: + LA93_132 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 34: + LA93_133 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 35: + LA93_134 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 36: + LA93_135 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 37: + LA93_136 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 38: + LA93_137 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 39: + LA93_138 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 40: + LA93_139 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 41: + LA93_140 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 42: + LA93_141 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 45 or LA93 == 46: + LA93_142 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 48: + LA93_143 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 49 or LA93 == 50 or LA93 == 51 or LA93 == 52 or LA93 == 53 or LA93 == 54 or LA93 == 55 or LA93 == 56 or LA93 == 57: + LA93_144 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + + elif LA93 == 35: + LA93 = self.input.LA(2) + if LA93 == 65: + LA93_145 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 58: + LA93_146 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 59: + LA93_147 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 60: + LA93_148 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == IDENTIFIER: + LA93_149 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 61: + LA93_150 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 25: + LA93_151 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 29 or LA93 == 30 or LA93 == 31 or LA93 == 32 or LA93 == 33: + LA93_152 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 34: + LA93_153 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 35: + LA93_154 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 36: + LA93_155 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 37: + LA93_156 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 38: + LA93_157 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 39: + LA93_158 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 40: + LA93_159 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 41: + LA93_160 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 42: + LA93_161 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 45 or LA93 == 46: + LA93_162 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 48: + LA93_163 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 49 or LA93 == 50 or LA93 == 51 or LA93 == 52 or LA93 == 53 or LA93 == 54 or LA93 == 55 or LA93 == 56 or LA93 == 57: + LA93_164 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + + elif LA93 == 36: + LA93 = self.input.LA(2) + if LA93 == 65: + LA93_165 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 58: + LA93_166 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 59: + LA93_167 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 60: + LA93_168 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == IDENTIFIER: + LA93_169 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 61: + LA93_170 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 25: + LA93_171 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 29 or LA93 == 30 or LA93 == 31 or LA93 == 32 or LA93 == 33: + LA93_172 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 34: + LA93_173 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 35: + LA93_174 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 36: + LA93_175 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 37: + LA93_176 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 38: + LA93_177 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 39: + LA93_178 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 40: + LA93_179 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 41: + LA93_180 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 42: + LA93_181 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 45 or LA93 == 46: + LA93_182 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 48: + LA93_183 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 49 or LA93 == 50 or LA93 == 51 or LA93 == 52 or LA93 == 53 or LA93 == 54 or LA93 == 55 or LA93 == 56 or LA93 == 57: + LA93_184 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + + elif LA93 == 37: + LA93 = self.input.LA(2) + if LA93 == 65: + LA93_185 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 58: + LA93_186 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 59: + LA93_187 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 60: + LA93_188 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == IDENTIFIER: + LA93_189 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 61: + LA93_190 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 25: + LA93_191 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 29 or LA93 == 30 or LA93 == 31 or LA93 == 32 or LA93 == 33: + LA93_192 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 34: + LA93_193 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 35: + LA93_194 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 36: + LA93_195 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 37: + LA93_196 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 38: + LA93_197 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 39: + LA93_198 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 40: + LA93_199 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 41: + LA93_200 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 42: + LA93_201 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 45 or LA93 == 46: + LA93_202 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 48: + LA93_203 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 49 or LA93 == 50 or LA93 == 51 or LA93 == 52 or LA93 == 53 or LA93 == 54 or LA93 == 55 or LA93 == 56 or LA93 == 57: + LA93_204 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + + elif LA93 == 38: + LA93 = self.input.LA(2) + if LA93 == 65: + LA93_205 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 58: + LA93_206 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 59: + LA93_207 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 60: + LA93_208 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == IDENTIFIER: + LA93_209 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 61: + LA93_210 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 25: + LA93_211 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 29 or LA93 == 30 or LA93 == 31 or LA93 == 32 or LA93 == 33: + LA93_212 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 34: + LA93_213 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 35: + LA93_214 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 36: + LA93_215 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 37: + LA93_216 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 38: + LA93_217 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 39: + LA93_218 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 40: + LA93_219 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 41: + LA93_220 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 42: + LA93_221 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 45 or LA93 == 46: + LA93_222 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 48: + LA93_223 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 49 or LA93 == 50 or LA93 == 51 or LA93 == 52 or LA93 == 53 or LA93 == 54 or LA93 == 55 or LA93 == 56 or LA93 == 57: + LA93_224 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + + elif LA93 == 39: + LA93 = self.input.LA(2) + if LA93 == 65: + LA93_225 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 58: + LA93_226 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 59: + LA93_227 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 60: + LA93_228 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == IDENTIFIER: + LA93_229 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 61: + LA93_230 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 25: + LA93_231 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 29 or LA93 == 30 or LA93 == 31 or LA93 == 32 or LA93 == 33: + LA93_232 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 34: + LA93_233 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 35: + LA93_234 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 36: + LA93_235 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 37: + LA93_236 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 38: + LA93_237 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 39: + LA93_238 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 40: + LA93_239 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 41: + LA93_240 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 42: + LA93_241 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 45 or LA93 == 46: + LA93_242 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 48: + LA93_243 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 49 or LA93 == 50 or LA93 == 51 or LA93 == 52 or LA93 == 53 or LA93 == 54 or LA93 == 55 or LA93 == 56 or LA93 == 57: + LA93_244 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + + elif LA93 == 40: + LA93 = self.input.LA(2) + if LA93 == 65: + LA93_245 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 58: + LA93_246 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 59: + LA93_247 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 60: + LA93_248 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == IDENTIFIER: + LA93_249 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 61: + LA93_250 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 25: + LA93_251 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 29 or LA93 == 30 or LA93 == 31 or LA93 == 32 or LA93 == 33: + LA93_252 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 34: + LA93_253 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 35: + LA93_254 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 36: + LA93_255 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 37: + LA93_256 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 38: + LA93_257 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 39: + LA93_258 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 40: + LA93_259 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 41: + LA93_260 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 42: + LA93_261 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 45 or LA93 == 46: + LA93_262 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 48: + LA93_263 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 49 or LA93 == 50 or LA93 == 51 or LA93 == 52 or LA93 == 53 or LA93 == 54 or LA93 == 55 or LA93 == 56 or LA93 == 57: + LA93_264 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + + elif LA93 == 41: + LA93 = self.input.LA(2) + if LA93 == 65: + LA93_265 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 58: + LA93_266 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 59: + LA93_267 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 60: + LA93_268 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == IDENTIFIER: + LA93_269 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 61: + LA93_270 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 25: + LA93_271 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 29 or LA93 == 30 or LA93 == 31 or LA93 == 32 or LA93 == 33: + LA93_272 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 34: + LA93_273 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 35: + LA93_274 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 36: + LA93_275 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 37: + LA93_276 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 38: + LA93_277 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 39: + LA93_278 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 40: + LA93_279 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 41: + LA93_280 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 42: + LA93_281 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 45 or LA93 == 46: + LA93_282 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 48: + LA93_283 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 49 or LA93 == 50 or LA93 == 51 or LA93 == 52 or LA93 == 53 or LA93 == 54 or LA93 == 55 or LA93 == 56 or LA93 == 57: + LA93_284 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + + elif LA93 == 42: + LA93 = self.input.LA(2) + if LA93 == 65: + LA93_285 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 58: + LA93_286 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 59: + LA93_287 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 60: + LA93_288 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == IDENTIFIER: + LA93_289 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 61: + LA93_290 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 25: + LA93_291 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 29 or LA93 == 30 or LA93 == 31 or LA93 == 32 or LA93 == 33: + LA93_292 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 34: + LA93_293 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 35: + LA93_294 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 36: + LA93_295 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 37: + LA93_296 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 38: + LA93_297 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 39: + LA93_298 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 40: + LA93_299 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 41: + LA93_300 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 42: + LA93_301 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 45 or LA93 == 46: + LA93_302 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 48: + LA93_303 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 49 or LA93 == 50 or LA93 == 51 or LA93 == 52 or LA93 == 53 or LA93 == 54 or LA93 == 55 or LA93 == 56 or LA93 == 57: + LA93_304 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + + elif LA93 == 45 or LA93 == 46: + LA93_40 = self.input.LA(2) + + if (LA93_40 == IDENTIFIER) : + LA93_305 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif (LA93_40 == 43) : + LA93_306 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + + + elif LA93 == 48: + LA93_41 = self.input.LA(2) + + if (LA93_41 == IDENTIFIER) : + LA93_307 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif (LA93_41 == 43) : + LA93_308 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + + + elif LA93 == 49 or LA93 == 50 or LA93 == 51 or LA93 == 52 or LA93 == 53 or LA93 == 54 or LA93 == 55 or LA93 == 56 or LA93 == 57 or LA93 == 58 or LA93 == 59 or LA93 == 60: + LA93 = self.input.LA(2) + if LA93 == 65: + LA93_309 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 58: + LA93_310 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 59: + LA93_311 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 60: + LA93_312 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == IDENTIFIER: + LA93_313 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 61: + LA93_314 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 25: + LA93_315 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 29 or LA93 == 30 or LA93 == 31 or LA93 == 32 or LA93 == 33: + LA93_316 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 34: + LA93_317 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 35: + LA93_318 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 36: + LA93_319 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 37: + LA93_320 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 38: + LA93_321 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 39: + LA93_322 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 40: + LA93_323 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 41: + LA93_324 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 42: + LA93_325 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 45 or LA93 == 46: + LA93_326 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 48: + LA93_327 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + elif LA93 == 49 or LA93 == 50 or LA93 == 51 or LA93 == 52 or LA93 == 53 or LA93 == 54 or LA93 == 55 or LA93 == 56 or LA93 == 57: + LA93_328 = self.input.LA(3) + + if (self.synpred185()) : + alt93 = 1 + + + + + if alt93 == 1: + # C.g:0:0: declaration + self.following.append(self.FOLLOW_declaration_in_compound_statement2210) + self.declaration() + self.following.pop() + if self.failed: + return retval + + + else: + break #loop93 + + + # C.g:501:21: ( statement_list )? + alt94 = 2 + LA94_0 = self.input.LA(1) + + if ((IDENTIFIER <= LA94_0 <= FLOATING_POINT_LITERAL) or (25 <= LA94_0 <= 26) or (29 <= LA94_0 <= 43) or (45 <= LA94_0 <= 46) or (48 <= LA94_0 <= 61) or LA94_0 == 65 or (67 <= LA94_0 <= 68) or (71 <= LA94_0 <= 73) or (76 <= LA94_0 <= 78) or (102 <= LA94_0 <= 107) or (109 <= LA94_0 <= 116)) : + alt94 = 1 + if alt94 == 1: + # C.g:0:0: statement_list + self.following.append(self.FOLLOW_statement_list_in_compound_statement2213) + self.statement_list() + self.following.pop() + if self.failed: + return retval + + + + self.match(self.input, 44, self.FOLLOW_44_in_compound_statement2216) + if self.failed: + return retval + + + + retval.stop = self.input.LT(-1) + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 66, compound_statement_StartIndex) + + pass + + return retval + + # $ANTLR end compound_statement + + + # $ANTLR start statement_list + # C.g:504:1: statement_list : ( statement )+ ; + def statement_list(self, ): + + statement_list_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 67): + return + + # C.g:505:2: ( ( statement )+ ) + # C.g:505:4: ( statement )+ + # C.g:505:4: ( statement )+ + cnt95 = 0 + while True: #loop95 + alt95 = 2 + LA95 = self.input.LA(1) + if LA95 == IDENTIFIER: + LA95 = self.input.LA(2) + if LA95 == 25 or LA95 == 29 or LA95 == 30 or LA95 == 31 or LA95 == 32 or LA95 == 33 or LA95 == 34 or LA95 == 35 or LA95 == 36 or LA95 == 37 or LA95 == 38 or LA95 == 39 or LA95 == 40 or LA95 == 41 or LA95 == 42 or LA95 == 45 or LA95 == 46 or LA95 == 47 or LA95 == 48 or LA95 == 49 or LA95 == 50 or LA95 == 51 or LA95 == 52 or LA95 == 53 or LA95 == 54 or LA95 == 55 or LA95 == 56 or LA95 == 57 or LA95 == 58 or LA95 == 59 or LA95 == 60: + alt95 = 1 + elif LA95 == 61: + LA95_47 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 63: + LA95_48 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 74: + LA95_49 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 65: + LA95_50 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 75: + LA95_51 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 71: + LA95_52 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 72: + LA95_53 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 28 or LA95 == 79 or LA95 == 80 or LA95 == 81 or LA95 == 82 or LA95 == 83 or LA95 == 84 or LA95 == 85 or LA95 == 86 or LA95 == 87 or LA95 == 88: + LA95_54 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == STRING_LITERAL: + LA95_55 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == IDENTIFIER: + LA95_56 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 69: + LA95_57 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 70: + LA95_58 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 67: + LA95_59 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 68: + LA95_60 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 100 or LA95 == 101: + LA95_61 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 96 or LA95 == 97 or LA95 == 98 or LA95 == 99: + LA95_62 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 94 or LA95 == 95: + LA95_63 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 76: + LA95_64 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 93: + LA95_65 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 92: + LA95_66 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 91: + LA95_67 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 90: + LA95_68 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 89: + LA95_69 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 27: + LA95_70 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + + elif LA95 == HEX_LITERAL: + LA95 = self.input.LA(2) + if LA95 == 63: + LA95_89 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 61: + LA95_90 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 74: + LA95_91 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 65: + LA95_92 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 75: + LA95_93 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 71: + LA95_94 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 72: + LA95_95 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 69: + LA95_96 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 70: + LA95_97 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 67: + LA95_98 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 68: + LA95_99 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 100 or LA95 == 101: + LA95_100 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 96 or LA95 == 97 or LA95 == 98 or LA95 == 99: + LA95_101 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 94 or LA95 == 95: + LA95_102 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 76: + LA95_103 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 93: + LA95_104 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 92: + LA95_105 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 91: + LA95_106 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 90: + LA95_107 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 89: + LA95_108 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 27: + LA95_109 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 25: + alt95 = 1 + elif LA95 == 28 or LA95 == 79 or LA95 == 80 or LA95 == 81 or LA95 == 82 or LA95 == 83 or LA95 == 84 or LA95 == 85 or LA95 == 86 or LA95 == 87 or LA95 == 88: + LA95_112 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + + elif LA95 == OCTAL_LITERAL: + LA95 = self.input.LA(2) + if LA95 == 63: + LA95_113 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 61: + LA95_114 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 74: + LA95_115 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 65: + LA95_116 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 75: + LA95_117 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 71: + LA95_118 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 72: + LA95_119 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 28 or LA95 == 79 or LA95 == 80 or LA95 == 81 or LA95 == 82 or LA95 == 83 or LA95 == 84 or LA95 == 85 or LA95 == 86 or LA95 == 87 or LA95 == 88: + LA95_120 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 69: + LA95_121 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 70: + LA95_122 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 67: + LA95_123 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 68: + LA95_124 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 100 or LA95 == 101: + LA95_125 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 96 or LA95 == 97 or LA95 == 98 or LA95 == 99: + LA95_126 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 94 or LA95 == 95: + LA95_127 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 76: + LA95_128 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 93: + LA95_129 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 92: + LA95_130 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 91: + LA95_131 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 90: + LA95_132 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 89: + LA95_133 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 27: + LA95_134 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 25: + alt95 = 1 + + elif LA95 == DECIMAL_LITERAL: + LA95 = self.input.LA(2) + if LA95 == 63: + LA95_137 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 61: + LA95_138 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 74: + LA95_139 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 65: + LA95_140 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 75: + LA95_141 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 71: + LA95_142 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 72: + LA95_143 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 28 or LA95 == 79 or LA95 == 80 or LA95 == 81 or LA95 == 82 or LA95 == 83 or LA95 == 84 or LA95 == 85 or LA95 == 86 or LA95 == 87 or LA95 == 88: + LA95_144 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 69: + LA95_145 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 70: + LA95_146 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 67: + LA95_147 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 68: + LA95_148 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 100 or LA95 == 101: + LA95_149 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 96 or LA95 == 97 or LA95 == 98 or LA95 == 99: + LA95_150 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 94 or LA95 == 95: + LA95_151 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 76: + LA95_152 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 93: + LA95_153 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 92: + LA95_154 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 91: + LA95_155 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 90: + LA95_156 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 89: + LA95_157 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 27: + LA95_158 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 25: + alt95 = 1 + + elif LA95 == CHARACTER_LITERAL: + LA95 = self.input.LA(2) + if LA95 == 63: + LA95_161 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 61: + LA95_162 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 74: + LA95_163 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 65: + LA95_164 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 75: + LA95_165 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 71: + LA95_166 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 72: + LA95_167 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 28 or LA95 == 79 or LA95 == 80 or LA95 == 81 or LA95 == 82 or LA95 == 83 or LA95 == 84 or LA95 == 85 or LA95 == 86 or LA95 == 87 or LA95 == 88: + LA95_168 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 69: + LA95_169 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 70: + LA95_170 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 67: + LA95_171 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 68: + LA95_172 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 100 or LA95 == 101: + LA95_173 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 96 or LA95 == 97 or LA95 == 98 or LA95 == 99: + LA95_174 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 94 or LA95 == 95: + LA95_175 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 76: + LA95_176 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 93: + LA95_177 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 92: + LA95_178 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 91: + LA95_179 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 90: + LA95_180 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 89: + LA95_181 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 27: + LA95_182 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 25: + alt95 = 1 + + elif LA95 == STRING_LITERAL: + LA95 = self.input.LA(2) + if LA95 == IDENTIFIER: + LA95_185 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 63: + LA95_186 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 61: + LA95_187 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 74: + LA95_188 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 65: + LA95_189 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 75: + LA95_190 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 71: + LA95_191 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 72: + LA95_192 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 69: + LA95_193 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 70: + LA95_194 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 67: + LA95_195 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 68: + LA95_196 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 100 or LA95 == 101: + LA95_197 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 96 or LA95 == 97 or LA95 == 98 or LA95 == 99: + LA95_198 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 94 or LA95 == 95: + LA95_199 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 76: + LA95_200 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 93: + LA95_201 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 92: + LA95_202 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 91: + LA95_203 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 90: + LA95_204 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 89: + LA95_205 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 27: + LA95_206 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 25: + alt95 = 1 + elif LA95 == STRING_LITERAL: + LA95_208 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 28 or LA95 == 79 or LA95 == 80 or LA95 == 81 or LA95 == 82 or LA95 == 83 or LA95 == 84 or LA95 == 85 or LA95 == 86 or LA95 == 87 or LA95 == 88: + LA95_210 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + + elif LA95 == FLOATING_POINT_LITERAL: + LA95 = self.input.LA(2) + if LA95 == 63: + LA95_211 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 61: + LA95_212 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 74: + LA95_213 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 65: + LA95_214 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 75: + LA95_215 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 71: + LA95_216 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 72: + LA95_217 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 69: + LA95_218 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 70: + LA95_219 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 67: + LA95_220 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 68: + LA95_221 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 100 or LA95 == 101: + LA95_222 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 96 or LA95 == 97 or LA95 == 98 or LA95 == 99: + LA95_223 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 94 or LA95 == 95: + LA95_224 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 76: + LA95_225 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 93: + LA95_226 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 92: + LA95_227 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 91: + LA95_228 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 90: + LA95_229 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 89: + LA95_230 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 27: + LA95_231 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 28 or LA95 == 79 or LA95 == 80 or LA95 == 81 or LA95 == 82 or LA95 == 83 or LA95 == 84 or LA95 == 85 or LA95 == 86 or LA95 == 87 or LA95 == 88: + LA95_233 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 25: + alt95 = 1 + + elif LA95 == 61: + LA95 = self.input.LA(2) + if LA95 == IDENTIFIER: + LA95_235 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == HEX_LITERAL: + LA95_236 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == OCTAL_LITERAL: + LA95_237 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == DECIMAL_LITERAL: + LA95_238 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == CHARACTER_LITERAL: + LA95_239 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == STRING_LITERAL: + LA95_240 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == FLOATING_POINT_LITERAL: + LA95_241 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 61: + LA95_242 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 71: + LA95_243 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 72: + LA95_244 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 65 or LA95 == 67 or LA95 == 68 or LA95 == 76 or LA95 == 77 or LA95 == 78: + LA95_245 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 73: + LA95_246 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 49 or LA95 == 50 or LA95 == 51 or LA95 == 52 or LA95 == 53 or LA95 == 54 or LA95 == 55 or LA95 == 56 or LA95 == 57 or LA95 == 58 or LA95 == 59 or LA95 == 60: + LA95_247 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 34: + LA95_248 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 35: + LA95_249 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 36: + LA95_250 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 37: + LA95_251 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 38: + LA95_252 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 39: + LA95_253 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 40: + LA95_254 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 41: + LA95_255 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 42: + LA95_256 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 45 or LA95 == 46: + LA95_257 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 48: + LA95_258 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + + elif LA95 == 71: + LA95 = self.input.LA(2) + if LA95 == IDENTIFIER: + LA95_259 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == HEX_LITERAL: + LA95_260 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == OCTAL_LITERAL: + LA95_261 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == DECIMAL_LITERAL: + LA95_262 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == CHARACTER_LITERAL: + LA95_263 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == STRING_LITERAL: + LA95_264 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == FLOATING_POINT_LITERAL: + LA95_265 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 61: + LA95_266 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 71: + LA95_267 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 72: + LA95_268 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 65 or LA95 == 67 or LA95 == 68 or LA95 == 76 or LA95 == 77 or LA95 == 78: + LA95_269 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 73: + LA95_270 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + + elif LA95 == 72: + LA95 = self.input.LA(2) + if LA95 == IDENTIFIER: + LA95_271 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == HEX_LITERAL: + LA95_272 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == OCTAL_LITERAL: + LA95_273 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == DECIMAL_LITERAL: + LA95_274 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == CHARACTER_LITERAL: + LA95_275 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == STRING_LITERAL: + LA95_276 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == FLOATING_POINT_LITERAL: + LA95_277 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 61: + LA95_278 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 71: + LA95_279 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 72: + LA95_280 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 65 or LA95 == 67 or LA95 == 68 or LA95 == 76 or LA95 == 77 or LA95 == 78: + LA95_281 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 73: + LA95_282 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + + elif LA95 == 65 or LA95 == 67 or LA95 == 68 or LA95 == 76 or LA95 == 77 or LA95 == 78: + LA95 = self.input.LA(2) + if LA95 == 61: + LA95_283 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == IDENTIFIER: + LA95_284 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == HEX_LITERAL: + LA95_285 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == OCTAL_LITERAL: + LA95_286 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == DECIMAL_LITERAL: + LA95_287 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == CHARACTER_LITERAL: + LA95_288 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == STRING_LITERAL: + LA95_289 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == FLOATING_POINT_LITERAL: + LA95_290 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 71: + LA95_291 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 72: + LA95_292 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 65 or LA95 == 67 or LA95 == 68 or LA95 == 76 or LA95 == 77 or LA95 == 78: + LA95_293 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 73: + LA95_294 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + + elif LA95 == 73: + LA95 = self.input.LA(2) + if LA95 == 61: + LA95_295 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == IDENTIFIER: + LA95_296 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == HEX_LITERAL: + LA95_297 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == OCTAL_LITERAL: + LA95_298 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == DECIMAL_LITERAL: + LA95_299 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == CHARACTER_LITERAL: + LA95_300 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == STRING_LITERAL: + LA95_301 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == FLOATING_POINT_LITERAL: + LA95_302 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 71: + LA95_303 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 72: + LA95_304 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 65 or LA95 == 67 or LA95 == 68 or LA95 == 76 or LA95 == 77 or LA95 == 78: + LA95_305 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + elif LA95 == 73: + LA95_306 = self.input.LA(3) + + if (self.synpred187()) : + alt95 = 1 + + + + elif LA95 == 25 or LA95 == 26 or LA95 == 29 or LA95 == 30 or LA95 == 31 or LA95 == 32 or LA95 == 33 or LA95 == 34 or LA95 == 35 or LA95 == 36 or LA95 == 37 or LA95 == 38 or LA95 == 39 or LA95 == 40 or LA95 == 41 or LA95 == 42 or LA95 == 43 or LA95 == 45 or LA95 == 46 or LA95 == 48 or LA95 == 49 or LA95 == 50 or LA95 == 51 or LA95 == 52 or LA95 == 53 or LA95 == 54 or LA95 == 55 or LA95 == 56 or LA95 == 57 or LA95 == 58 or LA95 == 59 or LA95 == 60 or LA95 == 102 or LA95 == 103 or LA95 == 104 or LA95 == 105 or LA95 == 106 or LA95 == 107 or LA95 == 109 or LA95 == 110 or LA95 == 111 or LA95 == 112 or LA95 == 113 or LA95 == 114 or LA95 == 115 or LA95 == 116: + alt95 = 1 + + if alt95 == 1: + # C.g:0:0: statement + self.following.append(self.FOLLOW_statement_in_statement_list2227) + self.statement() + self.following.pop() + if self.failed: + return + + + else: + if cnt95 >= 1: + break #loop95 + + if self.backtracking > 0: + self.failed = True + return + + eee = EarlyExitException(95, self.input) + raise eee + + cnt95 += 1 + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 67, statement_list_StartIndex) + + pass + + return + + # $ANTLR end statement_list + + class expression_statement_return(object): + def __init__(self): + self.start = None + self.stop = None + + + + # $ANTLR start expression_statement + # C.g:508:1: expression_statement : ( ';' | expression ';' ); + def expression_statement(self, ): + + retval = self.expression_statement_return() + retval.start = self.input.LT(1) + expression_statement_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 68): + return retval + + # C.g:509:2: ( ';' | expression ';' ) + alt96 = 2 + LA96_0 = self.input.LA(1) + + if (LA96_0 == 25) : + alt96 = 1 + elif ((IDENTIFIER <= LA96_0 <= FLOATING_POINT_LITERAL) or LA96_0 == 61 or LA96_0 == 65 or (67 <= LA96_0 <= 68) or (71 <= LA96_0 <= 73) or (76 <= LA96_0 <= 78)) : + alt96 = 2 + else: + if self.backtracking > 0: + self.failed = True + return retval + + nvae = NoViableAltException("508:1: expression_statement : ( ';' | expression ';' );", 96, 0, self.input) + + raise nvae + + if alt96 == 1: + # C.g:509:4: ';' + self.match(self.input, 25, self.FOLLOW_25_in_expression_statement2239) + if self.failed: + return retval + + + elif alt96 == 2: + # C.g:510:4: expression ';' + self.following.append(self.FOLLOW_expression_in_expression_statement2244) + self.expression() + self.following.pop() + if self.failed: + return retval + self.match(self.input, 25, self.FOLLOW_25_in_expression_statement2246) + if self.failed: + return retval + + + retval.stop = self.input.LT(-1) + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 68, expression_statement_StartIndex) + + pass + + return retval + + # $ANTLR end expression_statement + + + # $ANTLR start selection_statement + # C.g:513:1: selection_statement : ( 'if' '(' e= expression ')' statement ( options {k=1; backtrack=false; } : 'else' statement )? | 'switch' '(' expression ')' statement ); + def selection_statement(self, ): + + selection_statement_StartIndex = self.input.index() + e = None + + + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 69): + return + + # C.g:514:2: ( 'if' '(' e= expression ')' statement ( options {k=1; backtrack=false; } : 'else' statement )? | 'switch' '(' expression ')' statement ) + alt98 = 2 + LA98_0 = self.input.LA(1) + + if (LA98_0 == 107) : + alt98 = 1 + elif (LA98_0 == 109) : + alt98 = 2 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("513:1: selection_statement : ( 'if' '(' e= expression ')' statement ( options {k=1; backtrack=false; } : 'else' statement )? | 'switch' '(' expression ')' statement );", 98, 0, self.input) + + raise nvae + + if alt98 == 1: + # C.g:514:4: 'if' '(' e= expression ')' statement ( options {k=1; backtrack=false; } : 'else' statement )? + self.match(self.input, 107, self.FOLLOW_107_in_selection_statement2257) + if self.failed: + return + self.match(self.input, 61, self.FOLLOW_61_in_selection_statement2259) + if self.failed: + return + self.following.append(self.FOLLOW_expression_in_selection_statement2263) + e = self.expression() + self.following.pop() + if self.failed: + return + self.match(self.input, 62, self.FOLLOW_62_in_selection_statement2265) + if self.failed: + return + if self.backtracking == 0: + self.StorePredicateExpression(e.start.line, e.start.charPositionInLine, e.stop.line, e.stop.charPositionInLine, self.input.toString(e.start,e.stop)) + + self.following.append(self.FOLLOW_statement_in_selection_statement2269) + self.statement() + self.following.pop() + if self.failed: + return + # C.g:514:167: ( options {k=1; backtrack=false; } : 'else' statement )? + alt97 = 2 + LA97_0 = self.input.LA(1) + + if (LA97_0 == 108) : + alt97 = 1 + if alt97 == 1: + # C.g:514:200: 'else' statement + self.match(self.input, 108, self.FOLLOW_108_in_selection_statement2284) + if self.failed: + return + self.following.append(self.FOLLOW_statement_in_selection_statement2286) + self.statement() + self.following.pop() + if self.failed: + return + + + + + + elif alt98 == 2: + # C.g:515:4: 'switch' '(' expression ')' statement + self.match(self.input, 109, self.FOLLOW_109_in_selection_statement2293) + if self.failed: + return + self.match(self.input, 61, self.FOLLOW_61_in_selection_statement2295) + if self.failed: + return + self.following.append(self.FOLLOW_expression_in_selection_statement2297) + self.expression() + self.following.pop() + if self.failed: + return + self.match(self.input, 62, self.FOLLOW_62_in_selection_statement2299) + if self.failed: + return + self.following.append(self.FOLLOW_statement_in_selection_statement2301) + self.statement() + self.following.pop() + if self.failed: + return + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 69, selection_statement_StartIndex) + + pass + + return + + # $ANTLR end selection_statement + + + # $ANTLR start iteration_statement + # C.g:518:1: iteration_statement : ( 'while' '(' e= expression ')' statement | 'do' statement 'while' '(' e= expression ')' ';' | 'for' '(' expression_statement e= expression_statement ( expression )? ')' statement ); + def iteration_statement(self, ): + + iteration_statement_StartIndex = self.input.index() + e = None + + + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 70): + return + + # C.g:519:2: ( 'while' '(' e= expression ')' statement | 'do' statement 'while' '(' e= expression ')' ';' | 'for' '(' expression_statement e= expression_statement ( expression )? ')' statement ) + alt100 = 3 + LA100 = self.input.LA(1) + if LA100 == 110: + alt100 = 1 + elif LA100 == 111: + alt100 = 2 + elif LA100 == 112: + alt100 = 3 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("518:1: iteration_statement : ( 'while' '(' e= expression ')' statement | 'do' statement 'while' '(' e= expression ')' ';' | 'for' '(' expression_statement e= expression_statement ( expression )? ')' statement );", 100, 0, self.input) + + raise nvae + + if alt100 == 1: + # C.g:519:4: 'while' '(' e= expression ')' statement + self.match(self.input, 110, self.FOLLOW_110_in_iteration_statement2312) + if self.failed: + return + self.match(self.input, 61, self.FOLLOW_61_in_iteration_statement2314) + if self.failed: + return + self.following.append(self.FOLLOW_expression_in_iteration_statement2318) + e = self.expression() + self.following.pop() + if self.failed: + return + self.match(self.input, 62, self.FOLLOW_62_in_iteration_statement2320) + if self.failed: + return + self.following.append(self.FOLLOW_statement_in_iteration_statement2322) + self.statement() + self.following.pop() + if self.failed: + return + if self.backtracking == 0: + self.StorePredicateExpression(e.start.line, e.start.charPositionInLine, e.stop.line, e.stop.charPositionInLine, self.input.toString(e.start,e.stop)) + + + + elif alt100 == 2: + # C.g:520:4: 'do' statement 'while' '(' e= expression ')' ';' + self.match(self.input, 111, self.FOLLOW_111_in_iteration_statement2329) + if self.failed: + return + self.following.append(self.FOLLOW_statement_in_iteration_statement2331) + self.statement() + self.following.pop() + if self.failed: + return + self.match(self.input, 110, self.FOLLOW_110_in_iteration_statement2333) + if self.failed: + return + self.match(self.input, 61, self.FOLLOW_61_in_iteration_statement2335) + if self.failed: + return + self.following.append(self.FOLLOW_expression_in_iteration_statement2339) + e = self.expression() + self.following.pop() + if self.failed: + return + self.match(self.input, 62, self.FOLLOW_62_in_iteration_statement2341) + if self.failed: + return + self.match(self.input, 25, self.FOLLOW_25_in_iteration_statement2343) + if self.failed: + return + if self.backtracking == 0: + self.StorePredicateExpression(e.start.line, e.start.charPositionInLine, e.stop.line, e.stop.charPositionInLine, self.input.toString(e.start,e.stop)) + + + + elif alt100 == 3: + # C.g:521:4: 'for' '(' expression_statement e= expression_statement ( expression )? ')' statement + self.match(self.input, 112, self.FOLLOW_112_in_iteration_statement2350) + if self.failed: + return + self.match(self.input, 61, self.FOLLOW_61_in_iteration_statement2352) + if self.failed: + return + self.following.append(self.FOLLOW_expression_statement_in_iteration_statement2354) + self.expression_statement() + self.following.pop() + if self.failed: + return + self.following.append(self.FOLLOW_expression_statement_in_iteration_statement2358) + e = self.expression_statement() + self.following.pop() + if self.failed: + return + # C.g:521:58: ( expression )? + alt99 = 2 + LA99_0 = self.input.LA(1) + + if ((IDENTIFIER <= LA99_0 <= FLOATING_POINT_LITERAL) or LA99_0 == 61 or LA99_0 == 65 or (67 <= LA99_0 <= 68) or (71 <= LA99_0 <= 73) or (76 <= LA99_0 <= 78)) : + alt99 = 1 + if alt99 == 1: + # C.g:0:0: expression + self.following.append(self.FOLLOW_expression_in_iteration_statement2360) + self.expression() + self.following.pop() + if self.failed: + return + + + + self.match(self.input, 62, self.FOLLOW_62_in_iteration_statement2363) + if self.failed: + return + self.following.append(self.FOLLOW_statement_in_iteration_statement2365) + self.statement() + self.following.pop() + if self.failed: + return + if self.backtracking == 0: + self.StorePredicateExpression(e.start.line, e.start.charPositionInLine, e.stop.line, e.stop.charPositionInLine, self.input.toString(e.start,e.stop)) + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 70, iteration_statement_StartIndex) + + pass + + return + + # $ANTLR end iteration_statement + + + # $ANTLR start jump_statement + # C.g:524:1: jump_statement : ( 'goto' IDENTIFIER ';' | 'continue' ';' | 'break' ';' | 'return' ';' | 'return' expression ';' ); + def jump_statement(self, ): + + jump_statement_StartIndex = self.input.index() + try: + try: + if self.backtracking > 0 and self.alreadyParsedRule(self.input, 71): + return + + # C.g:525:2: ( 'goto' IDENTIFIER ';' | 'continue' ';' | 'break' ';' | 'return' ';' | 'return' expression ';' ) + alt101 = 5 + LA101 = self.input.LA(1) + if LA101 == 113: + alt101 = 1 + elif LA101 == 114: + alt101 = 2 + elif LA101 == 115: + alt101 = 3 + elif LA101 == 116: + LA101_4 = self.input.LA(2) + + if (LA101_4 == 25) : + alt101 = 4 + elif ((IDENTIFIER <= LA101_4 <= FLOATING_POINT_LITERAL) or LA101_4 == 61 or LA101_4 == 65 or (67 <= LA101_4 <= 68) or (71 <= LA101_4 <= 73) or (76 <= LA101_4 <= 78)) : + alt101 = 5 + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("524:1: jump_statement : ( 'goto' IDENTIFIER ';' | 'continue' ';' | 'break' ';' | 'return' ';' | 'return' expression ';' );", 101, 4, self.input) + + raise nvae + + else: + if self.backtracking > 0: + self.failed = True + return + + nvae = NoViableAltException("524:1: jump_statement : ( 'goto' IDENTIFIER ';' | 'continue' ';' | 'break' ';' | 'return' ';' | 'return' expression ';' );", 101, 0, self.input) + + raise nvae + + if alt101 == 1: + # C.g:525:4: 'goto' IDENTIFIER ';' + self.match(self.input, 113, self.FOLLOW_113_in_jump_statement2378) + if self.failed: + return + self.match(self.input, IDENTIFIER, self.FOLLOW_IDENTIFIER_in_jump_statement2380) + if self.failed: + return + self.match(self.input, 25, self.FOLLOW_25_in_jump_statement2382) + if self.failed: + return + + + elif alt101 == 2: + # C.g:526:4: 'continue' ';' + self.match(self.input, 114, self.FOLLOW_114_in_jump_statement2387) + if self.failed: + return + self.match(self.input, 25, self.FOLLOW_25_in_jump_statement2389) + if self.failed: + return + + + elif alt101 == 3: + # C.g:527:4: 'break' ';' + self.match(self.input, 115, self.FOLLOW_115_in_jump_statement2394) + if self.failed: + return + self.match(self.input, 25, self.FOLLOW_25_in_jump_statement2396) + if self.failed: + return + + + elif alt101 == 4: + # C.g:528:4: 'return' ';' + self.match(self.input, 116, self.FOLLOW_116_in_jump_statement2401) + if self.failed: + return + self.match(self.input, 25, self.FOLLOW_25_in_jump_statement2403) + if self.failed: + return + + + elif alt101 == 5: + # C.g:529:4: 'return' expression ';' + self.match(self.input, 116, self.FOLLOW_116_in_jump_statement2408) + if self.failed: + return + self.following.append(self.FOLLOW_expression_in_jump_statement2410) + self.expression() + self.following.pop() + if self.failed: + return + self.match(self.input, 25, self.FOLLOW_25_in_jump_statement2412) + if self.failed: + return + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + if self.backtracking > 0: + self.memoize(self.input, 71, jump_statement_StartIndex) + + pass + + return + + # $ANTLR end jump_statement + + # $ANTLR start synpred2 + def synpred2_fragment(self, ): + # C.g:67:6: ( declaration_specifiers ) + # C.g:67:6: declaration_specifiers + self.following.append(self.FOLLOW_declaration_specifiers_in_synpred290) + self.declaration_specifiers() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred2 + + + + # $ANTLR start synpred4 + def synpred4_fragment(self, ): + # C.g:67:4: ( ( declaration_specifiers )? declarator ( declaration )* '{' ) + # C.g:67:6: ( declaration_specifiers )? declarator ( declaration )* '{' + # C.g:67:6: ( declaration_specifiers )? + alt102 = 2 + LA102 = self.input.LA(1) + if LA102 == 29 or LA102 == 30 or LA102 == 31 or LA102 == 32 or LA102 == 33 or LA102 == 34 or LA102 == 35 or LA102 == 36 or LA102 == 37 or LA102 == 38 or LA102 == 39 or LA102 == 40 or LA102 == 41 or LA102 == 42 or LA102 == 45 or LA102 == 46 or LA102 == 48 or LA102 == 49 or LA102 == 50 or LA102 == 51 or LA102 == 52 or LA102 == 53 or LA102 == 54 or LA102 == 55 or LA102 == 56 or LA102 == 57: + alt102 = 1 + elif LA102 == IDENTIFIER: + LA102 = self.input.LA(2) + if LA102 == 65: + alt102 = 1 + elif LA102 == 58: + LA102_21 = self.input.LA(3) + + if (self.synpred2()) : + alt102 = 1 + elif LA102 == 59: + LA102_22 = self.input.LA(3) + + if (self.synpred2()) : + alt102 = 1 + elif LA102 == 60: + LA102_23 = self.input.LA(3) + + if (self.synpred2()) : + alt102 = 1 + elif LA102 == IDENTIFIER: + LA102_24 = self.input.LA(3) + + if (self.synpred2()) : + alt102 = 1 + elif LA102 == 61: + LA102_25 = self.input.LA(3) + + if (self.synpred2()) : + alt102 = 1 + elif LA102 == 29 or LA102 == 30 or LA102 == 31 or LA102 == 32 or LA102 == 33: + LA102_26 = self.input.LA(3) + + if (self.synpred2()) : + alt102 = 1 + elif LA102 == 34: + LA102_27 = self.input.LA(3) + + if (self.synpred2()) : + alt102 = 1 + elif LA102 == 35: + LA102_28 = self.input.LA(3) + + if (self.synpred2()) : + alt102 = 1 + elif LA102 == 36: + LA102_29 = self.input.LA(3) + + if (self.synpred2()) : + alt102 = 1 + elif LA102 == 37: + LA102_30 = self.input.LA(3) + + if (self.synpred2()) : + alt102 = 1 + elif LA102 == 38: + LA102_31 = self.input.LA(3) + + if (self.synpred2()) : + alt102 = 1 + elif LA102 == 39: + LA102_32 = self.input.LA(3) + + if (self.synpred2()) : + alt102 = 1 + elif LA102 == 40: + LA102_33 = self.input.LA(3) + + if (self.synpred2()) : + alt102 = 1 + elif LA102 == 41: + LA102_34 = self.input.LA(3) + + if (self.synpred2()) : + alt102 = 1 + elif LA102 == 42: + LA102_35 = self.input.LA(3) + + if (self.synpred2()) : + alt102 = 1 + elif LA102 == 45 or LA102 == 46: + LA102_36 = self.input.LA(3) + + if (self.synpred2()) : + alt102 = 1 + elif LA102 == 48: + LA102_37 = self.input.LA(3) + + if (self.synpred2()) : + alt102 = 1 + elif LA102 == 49 or LA102 == 50 or LA102 == 51 or LA102 == 52 or LA102 == 53 or LA102 == 54 or LA102 == 55 or LA102 == 56 or LA102 == 57: + LA102_38 = self.input.LA(3) + + if (self.synpred2()) : + alt102 = 1 + elif LA102 == 58: + LA102_14 = self.input.LA(2) + + if (self.synpred2()) : + alt102 = 1 + elif LA102 == 59: + LA102_16 = self.input.LA(2) + + if (self.synpred2()) : + alt102 = 1 + elif LA102 == 60: + LA102_17 = self.input.LA(2) + + if (self.synpred2()) : + alt102 = 1 + if alt102 == 1: + # C.g:0:0: declaration_specifiers + self.following.append(self.FOLLOW_declaration_specifiers_in_synpred490) + self.declaration_specifiers() + self.following.pop() + if self.failed: + return + + + + self.following.append(self.FOLLOW_declarator_in_synpred493) + self.declarator() + self.following.pop() + if self.failed: + return + # C.g:67:41: ( declaration )* + while True: #loop103 + alt103 = 2 + LA103_0 = self.input.LA(1) + + if (LA103_0 == IDENTIFIER or LA103_0 == 26 or (29 <= LA103_0 <= 42) or (45 <= LA103_0 <= 46) or (48 <= LA103_0 <= 60)) : + alt103 = 1 + + + if alt103 == 1: + # C.g:0:0: declaration + self.following.append(self.FOLLOW_declaration_in_synpred495) + self.declaration() + self.following.pop() + if self.failed: + return + + + else: + break #loop103 + + + self.match(self.input, 43, self.FOLLOW_43_in_synpred498) + if self.failed: + return + + + # $ANTLR end synpred4 + + + + # $ANTLR start synpred5 + def synpred5_fragment(self, ): + # C.g:68:4: ( declaration ) + # C.g:68:4: declaration + self.following.append(self.FOLLOW_declaration_in_synpred5108) + self.declaration() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred5 + + + + # $ANTLR start synpred7 + def synpred7_fragment(self, ): + # C.g:94:6: ( declaration_specifiers ) + # C.g:94:6: declaration_specifiers + self.following.append(self.FOLLOW_declaration_specifiers_in_synpred7147) + self.declaration_specifiers() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred7 + + + + # $ANTLR start synpred10 + def synpred10_fragment(self, ): + # C.g:115:18: ( declaration_specifiers ) + # C.g:115:18: declaration_specifiers + self.following.append(self.FOLLOW_declaration_specifiers_in_synpred10197) + self.declaration_specifiers() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred10 + + + + # $ANTLR start synpred14 + def synpred14_fragment(self, ): + # C.g:132:7: ( type_specifier ) + # C.g:132:7: type_specifier + self.following.append(self.FOLLOW_type_specifier_in_synpred14262) + self.type_specifier() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred14 + + + + # $ANTLR start synpred15 + def synpred15_fragment(self, ): + # C.g:133:13: ( type_qualifier ) + # C.g:133:13: type_qualifier + self.following.append(self.FOLLOW_type_qualifier_in_synpred15276) + self.type_qualifier() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred15 + + + + # $ANTLR start synpred33 + def synpred33_fragment(self, ): + # C.g:173:16: ( type_qualifier ) + # C.g:173:16: type_qualifier + self.following.append(self.FOLLOW_type_qualifier_in_synpred33434) + self.type_qualifier() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred33 + + + + # $ANTLR start synpred34 + def synpred34_fragment(self, ): + # C.g:173:4: ( IDENTIFIER ( type_qualifier )* declarator ) + # C.g:173:5: IDENTIFIER ( type_qualifier )* declarator + self.match(self.input, IDENTIFIER, self.FOLLOW_IDENTIFIER_in_synpred34432) + if self.failed: + return + # C.g:173:16: ( type_qualifier )* + while True: #loop106 + alt106 = 2 + LA106 = self.input.LA(1) + if LA106 == 58: + LA106_2 = self.input.LA(2) + + if (self.synpred33()) : + alt106 = 1 + + + elif LA106 == 59: + LA106_3 = self.input.LA(2) + + if (self.synpred33()) : + alt106 = 1 + + + elif LA106 == 60: + LA106_4 = self.input.LA(2) + + if (self.synpred33()) : + alt106 = 1 + + + elif LA106 == 49 or LA106 == 50 or LA106 == 51 or LA106 == 52 or LA106 == 53 or LA106 == 54 or LA106 == 55 or LA106 == 56 or LA106 == 57: + alt106 = 1 + + if alt106 == 1: + # C.g:0:0: type_qualifier + self.following.append(self.FOLLOW_type_qualifier_in_synpred34434) + self.type_qualifier() + self.following.pop() + if self.failed: + return + + + else: + break #loop106 + + + self.following.append(self.FOLLOW_declarator_in_synpred34437) + self.declarator() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred34 + + + + # $ANTLR start synpred39 + def synpred39_fragment(self, ): + # C.g:201:6: ( type_qualifier ) + # C.g:201:6: type_qualifier + self.following.append(self.FOLLOW_type_qualifier_in_synpred39556) + self.type_qualifier() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred39 + + + + # $ANTLR start synpred40 + def synpred40_fragment(self, ): + # C.g:201:23: ( type_specifier ) + # C.g:201:23: type_specifier + self.following.append(self.FOLLOW_type_specifier_in_synpred40560) + self.type_specifier() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred40 + + + + # $ANTLR start synpred65 + def synpred65_fragment(self, ): + # C.g:244:4: ( ( pointer )? ( 'EFIAPI' )? ( 'EFI_BOOTSERVICE' )? ( 'EFI_RUNTIMESERVICE' )? direct_declarator ) + # C.g:244:4: ( pointer )? ( 'EFIAPI' )? ( 'EFI_BOOTSERVICE' )? ( 'EFI_RUNTIMESERVICE' )? direct_declarator + # C.g:244:4: ( pointer )? + alt111 = 2 + LA111_0 = self.input.LA(1) + + if (LA111_0 == 65) : + alt111 = 1 + if alt111 == 1: + # C.g:0:0: pointer + self.following.append(self.FOLLOW_pointer_in_synpred65769) + self.pointer() + self.following.pop() + if self.failed: + return + + + + # C.g:244:13: ( 'EFIAPI' )? + alt112 = 2 + LA112_0 = self.input.LA(1) + + if (LA112_0 == 58) : + alt112 = 1 + if alt112 == 1: + # C.g:244:14: 'EFIAPI' + self.match(self.input, 58, self.FOLLOW_58_in_synpred65773) + if self.failed: + return + + + + # C.g:244:25: ( 'EFI_BOOTSERVICE' )? + alt113 = 2 + LA113_0 = self.input.LA(1) + + if (LA113_0 == 59) : + alt113 = 1 + if alt113 == 1: + # C.g:244:26: 'EFI_BOOTSERVICE' + self.match(self.input, 59, self.FOLLOW_59_in_synpred65778) + if self.failed: + return + + + + # C.g:244:46: ( 'EFI_RUNTIMESERVICE' )? + alt114 = 2 + LA114_0 = self.input.LA(1) + + if (LA114_0 == 60) : + alt114 = 1 + if alt114 == 1: + # C.g:244:47: 'EFI_RUNTIMESERVICE' + self.match(self.input, 60, self.FOLLOW_60_in_synpred65783) + if self.failed: + return + + + + self.following.append(self.FOLLOW_direct_declarator_in_synpred65787) + self.direct_declarator() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred65 + + + + # $ANTLR start synpred66 + def synpred66_fragment(self, ): + # C.g:250:15: ( declarator_suffix ) + # C.g:250:15: declarator_suffix + self.following.append(self.FOLLOW_declarator_suffix_in_synpred66806) + self.declarator_suffix() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred66 + + + + # $ANTLR start synpred68 + def synpred68_fragment(self, ): + # C.g:251:9: ( 'EFIAPI' ) + # C.g:251:9: 'EFIAPI' + self.match(self.input, 58, self.FOLLOW_58_in_synpred68815) + if self.failed: + return + + + # $ANTLR end synpred68 + + + + # $ANTLR start synpred69 + def synpred69_fragment(self, ): + # C.g:251:35: ( declarator_suffix ) + # C.g:251:35: declarator_suffix + self.following.append(self.FOLLOW_declarator_suffix_in_synpred69823) + self.declarator_suffix() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred69 + + + + # $ANTLR start synpred72 + def synpred72_fragment(self, ): + # C.g:257:9: ( '(' parameter_type_list ')' ) + # C.g:257:9: '(' parameter_type_list ')' + self.match(self.input, 61, self.FOLLOW_61_in_synpred72863) + if self.failed: + return + self.following.append(self.FOLLOW_parameter_type_list_in_synpred72865) + self.parameter_type_list() + self.following.pop() + if self.failed: + return + self.match(self.input, 62, self.FOLLOW_62_in_synpred72867) + if self.failed: + return + + + # $ANTLR end synpred72 + + + + # $ANTLR start synpred73 + def synpred73_fragment(self, ): + # C.g:258:9: ( '(' identifier_list ')' ) + # C.g:258:9: '(' identifier_list ')' + self.match(self.input, 61, self.FOLLOW_61_in_synpred73877) + if self.failed: + return + self.following.append(self.FOLLOW_identifier_list_in_synpred73879) + self.identifier_list() + self.following.pop() + if self.failed: + return + self.match(self.input, 62, self.FOLLOW_62_in_synpred73881) + if self.failed: + return + + + # $ANTLR end synpred73 + + + + # $ANTLR start synpred74 + def synpred74_fragment(self, ): + # C.g:263:8: ( type_qualifier ) + # C.g:263:8: type_qualifier + self.following.append(self.FOLLOW_type_qualifier_in_synpred74906) + self.type_qualifier() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred74 + + + + # $ANTLR start synpred75 + def synpred75_fragment(self, ): + # C.g:263:24: ( pointer ) + # C.g:263:24: pointer + self.following.append(self.FOLLOW_pointer_in_synpred75909) + self.pointer() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred75 + + + + # $ANTLR start synpred76 + def synpred76_fragment(self, ): + # C.g:263:4: ( '*' ( type_qualifier )+ ( pointer )? ) + # C.g:263:4: '*' ( type_qualifier )+ ( pointer )? + self.match(self.input, 65, self.FOLLOW_65_in_synpred76904) + if self.failed: + return + # C.g:263:8: ( type_qualifier )+ + cnt116 = 0 + while True: #loop116 + alt116 = 2 + LA116_0 = self.input.LA(1) + + if ((49 <= LA116_0 <= 60)) : + alt116 = 1 + + + if alt116 == 1: + # C.g:0:0: type_qualifier + self.following.append(self.FOLLOW_type_qualifier_in_synpred76906) + self.type_qualifier() + self.following.pop() + if self.failed: + return + + + else: + if cnt116 >= 1: + break #loop116 + + if self.backtracking > 0: + self.failed = True + return + + eee = EarlyExitException(116, self.input) + raise eee + + cnt116 += 1 + + + # C.g:263:24: ( pointer )? + alt117 = 2 + LA117_0 = self.input.LA(1) + + if (LA117_0 == 65) : + alt117 = 1 + if alt117 == 1: + # C.g:0:0: pointer + self.following.append(self.FOLLOW_pointer_in_synpred76909) + self.pointer() + self.following.pop() + if self.failed: + return + + + + + + # $ANTLR end synpred76 + + + + # $ANTLR start synpred77 + def synpred77_fragment(self, ): + # C.g:264:4: ( '*' pointer ) + # C.g:264:4: '*' pointer + self.match(self.input, 65, self.FOLLOW_65_in_synpred77915) + if self.failed: + return + self.following.append(self.FOLLOW_pointer_in_synpred77917) + self.pointer() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred77 + + + + # $ANTLR start synpred80 + def synpred80_fragment(self, ): + # C.g:273:32: ( 'OPTIONAL' ) + # C.g:273:32: 'OPTIONAL' + self.match(self.input, 53, self.FOLLOW_53_in_synpred80962) + if self.failed: + return + + + # $ANTLR end synpred80 + + + + # $ANTLR start synpred81 + def synpred81_fragment(self, ): + # C.g:273:27: ( ',' ( 'OPTIONAL' )? parameter_declaration ) + # C.g:273:27: ',' ( 'OPTIONAL' )? parameter_declaration + self.match(self.input, 27, self.FOLLOW_27_in_synpred81959) + if self.failed: + return + # C.g:273:31: ( 'OPTIONAL' )? + alt119 = 2 + LA119_0 = self.input.LA(1) + + if (LA119_0 == 53) : + LA119_1 = self.input.LA(2) + + if (self.synpred80()) : + alt119 = 1 + if alt119 == 1: + # C.g:273:32: 'OPTIONAL' + self.match(self.input, 53, self.FOLLOW_53_in_synpred81962) + if self.failed: + return + + + + self.following.append(self.FOLLOW_parameter_declaration_in_synpred81966) + self.parameter_declaration() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred81 + + + + # $ANTLR start synpred82 + def synpred82_fragment(self, ): + # C.g:277:28: ( declarator ) + # C.g:277:28: declarator + self.following.append(self.FOLLOW_declarator_in_synpred82982) + self.declarator() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred82 + + + + # $ANTLR start synpred83 + def synpred83_fragment(self, ): + # C.g:277:39: ( abstract_declarator ) + # C.g:277:39: abstract_declarator + self.following.append(self.FOLLOW_abstract_declarator_in_synpred83984) + self.abstract_declarator() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred83 + + + + # $ANTLR start synpred85 + def synpred85_fragment(self, ): + # C.g:277:4: ( declaration_specifiers ( declarator | abstract_declarator )* ( 'OPTIONAL' )? ) + # C.g:277:4: declaration_specifiers ( declarator | abstract_declarator )* ( 'OPTIONAL' )? + self.following.append(self.FOLLOW_declaration_specifiers_in_synpred85979) + self.declaration_specifiers() + self.following.pop() + if self.failed: + return + # C.g:277:27: ( declarator | abstract_declarator )* + while True: #loop120 + alt120 = 3 + LA120 = self.input.LA(1) + if LA120 == 65: + LA120_3 = self.input.LA(2) + + if (self.synpred82()) : + alt120 = 1 + elif (self.synpred83()) : + alt120 = 2 + + + elif LA120 == IDENTIFIER or LA120 == 58 or LA120 == 59 or LA120 == 60: + alt120 = 1 + elif LA120 == 61: + LA120 = self.input.LA(2) + if LA120 == 29 or LA120 == 30 or LA120 == 31 or LA120 == 32 or LA120 == 33 or LA120 == 34 or LA120 == 35 or LA120 == 36 or LA120 == 37 or LA120 == 38 or LA120 == 39 or LA120 == 40 or LA120 == 41 or LA120 == 42 or LA120 == 45 or LA120 == 46 or LA120 == 48 or LA120 == 49 or LA120 == 50 or LA120 == 51 or LA120 == 52 or LA120 == 53 or LA120 == 54 or LA120 == 55 or LA120 == 56 or LA120 == 57 or LA120 == 62 or LA120 == 63: + alt120 = 2 + elif LA120 == 58: + LA120_21 = self.input.LA(3) + + if (self.synpred82()) : + alt120 = 1 + elif (self.synpred83()) : + alt120 = 2 + + + elif LA120 == 65: + LA120_22 = self.input.LA(3) + + if (self.synpred82()) : + alt120 = 1 + elif (self.synpred83()) : + alt120 = 2 + + + elif LA120 == 59: + LA120_23 = self.input.LA(3) + + if (self.synpred82()) : + alt120 = 1 + elif (self.synpred83()) : + alt120 = 2 + + + elif LA120 == 60: + LA120_24 = self.input.LA(3) + + if (self.synpred82()) : + alt120 = 1 + elif (self.synpred83()) : + alt120 = 2 + + + elif LA120 == IDENTIFIER: + LA120_25 = self.input.LA(3) + + if (self.synpred82()) : + alt120 = 1 + elif (self.synpred83()) : + alt120 = 2 + + + elif LA120 == 61: + LA120_26 = self.input.LA(3) + + if (self.synpred82()) : + alt120 = 1 + elif (self.synpred83()) : + alt120 = 2 + + + + elif LA120 == 63: + alt120 = 2 + + if alt120 == 1: + # C.g:277:28: declarator + self.following.append(self.FOLLOW_declarator_in_synpred85982) + self.declarator() + self.following.pop() + if self.failed: + return + + + elif alt120 == 2: + # C.g:277:39: abstract_declarator + self.following.append(self.FOLLOW_abstract_declarator_in_synpred85984) + self.abstract_declarator() + self.following.pop() + if self.failed: + return + + + else: + break #loop120 + + + # C.g:277:61: ( 'OPTIONAL' )? + alt121 = 2 + LA121_0 = self.input.LA(1) + + if (LA121_0 == 53) : + alt121 = 1 + if alt121 == 1: + # C.g:277:62: 'OPTIONAL' + self.match(self.input, 53, self.FOLLOW_53_in_synpred85989) + if self.failed: + return + + + + + + # $ANTLR end synpred85 + + + + # $ANTLR start synpred89 + def synpred89_fragment(self, ): + # C.g:288:4: ( specifier_qualifier_list ( abstract_declarator )? ) + # C.g:288:4: specifier_qualifier_list ( abstract_declarator )? + self.following.append(self.FOLLOW_specifier_qualifier_list_in_synpred891031) + self.specifier_qualifier_list() + self.following.pop() + if self.failed: + return + # C.g:288:29: ( abstract_declarator )? + alt122 = 2 + LA122_0 = self.input.LA(1) + + if (LA122_0 == 61 or LA122_0 == 63 or LA122_0 == 65) : + alt122 = 1 + if alt122 == 1: + # C.g:0:0: abstract_declarator + self.following.append(self.FOLLOW_abstract_declarator_in_synpred891033) + self.abstract_declarator() + self.following.pop() + if self.failed: + return + + + + + + # $ANTLR end synpred89 + + + + # $ANTLR start synpred90 + def synpred90_fragment(self, ): + # C.g:293:12: ( direct_abstract_declarator ) + # C.g:293:12: direct_abstract_declarator + self.following.append(self.FOLLOW_direct_abstract_declarator_in_synpred901052) + self.direct_abstract_declarator() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred90 + + + + # $ANTLR start synpred92 + def synpred92_fragment(self, ): + # C.g:298:6: ( '(' abstract_declarator ')' ) + # C.g:298:6: '(' abstract_declarator ')' + self.match(self.input, 61, self.FOLLOW_61_in_synpred921071) + if self.failed: + return + self.following.append(self.FOLLOW_abstract_declarator_in_synpred921073) + self.abstract_declarator() + self.following.pop() + if self.failed: + return + self.match(self.input, 62, self.FOLLOW_62_in_synpred921075) + if self.failed: + return + + + # $ANTLR end synpred92 + + + + # $ANTLR start synpred93 + def synpred93_fragment(self, ): + # C.g:298:65: ( abstract_declarator_suffix ) + # C.g:298:65: abstract_declarator_suffix + self.following.append(self.FOLLOW_abstract_declarator_suffix_in_synpred931083) + self.abstract_declarator_suffix() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred93 + + + + # $ANTLR start synpred108 + def synpred108_fragment(self, ): + # C.g:333:4: ( '(' type_name ')' cast_expression ) + # C.g:333:4: '(' type_name ')' cast_expression + self.match(self.input, 61, self.FOLLOW_61_in_synpred1081267) + if self.failed: + return + self.following.append(self.FOLLOW_type_name_in_synpred1081269) + self.type_name() + self.following.pop() + if self.failed: + return + self.match(self.input, 62, self.FOLLOW_62_in_synpred1081271) + if self.failed: + return + self.following.append(self.FOLLOW_cast_expression_in_synpred1081273) + self.cast_expression() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred108 + + + + # $ANTLR start synpred113 + def synpred113_fragment(self, ): + # C.g:342:4: ( 'sizeof' unary_expression ) + # C.g:342:4: 'sizeof' unary_expression + self.match(self.input, 73, self.FOLLOW_73_in_synpred1131315) + if self.failed: + return + self.following.append(self.FOLLOW_unary_expression_in_synpred1131317) + self.unary_expression() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred113 + + + + # $ANTLR start synpred116 + def synpred116_fragment(self, ): + # C.g:356:13: ( '(' argument_expression_list ')' ) + # C.g:356:13: '(' argument_expression_list ')' + self.match(self.input, 61, self.FOLLOW_61_in_synpred1161405) + if self.failed: + return + self.following.append(self.FOLLOW_argument_expression_list_in_synpred1161409) + self.argument_expression_list() + self.following.pop() + if self.failed: + return + self.match(self.input, 62, self.FOLLOW_62_in_synpred1161413) + if self.failed: + return + + + # $ANTLR end synpred116 + + + + # $ANTLR start synpred117 + def synpred117_fragment(self, ): + # C.g:357:13: ( '(' macro_parameter_list ')' ) + # C.g:357:13: '(' macro_parameter_list ')' + self.match(self.input, 61, self.FOLLOW_61_in_synpred1171429) + if self.failed: + return + self.following.append(self.FOLLOW_macro_parameter_list_in_synpred1171431) + self.macro_parameter_list() + self.following.pop() + if self.failed: + return + self.match(self.input, 62, self.FOLLOW_62_in_synpred1171433) + if self.failed: + return + + + # $ANTLR end synpred117 + + + + # $ANTLR start synpred119 + def synpred119_fragment(self, ): + # C.g:359:13: ( '*' IDENTIFIER ) + # C.g:359:13: '*' IDENTIFIER + self.match(self.input, 65, self.FOLLOW_65_in_synpred1191467) + if self.failed: + return + self.match(self.input, IDENTIFIER, self.FOLLOW_IDENTIFIER_in_synpred1191471) + if self.failed: + return + + + # $ANTLR end synpred119 + + + + # $ANTLR start synpred136 + def synpred136_fragment(self, ): + # C.g:390:20: ( STRING_LITERAL ) + # C.g:390:20: STRING_LITERAL + self.match(self.input, STRING_LITERAL, self.FOLLOW_STRING_LITERAL_in_synpred1361668) + if self.failed: + return + + + # $ANTLR end synpred136 + + + + # $ANTLR start synpred137 + def synpred137_fragment(self, ): + # C.g:390:8: ( ( IDENTIFIER )* ( STRING_LITERAL )+ ) + # C.g:390:8: ( IDENTIFIER )* ( STRING_LITERAL )+ + # C.g:390:8: ( IDENTIFIER )* + while True: #loop125 + alt125 = 2 + LA125_0 = self.input.LA(1) + + if (LA125_0 == IDENTIFIER) : + alt125 = 1 + + + if alt125 == 1: + # C.g:0:0: IDENTIFIER + self.match(self.input, IDENTIFIER, self.FOLLOW_IDENTIFIER_in_synpred1371665) + if self.failed: + return + + + else: + break #loop125 + + + # C.g:390:20: ( STRING_LITERAL )+ + cnt126 = 0 + while True: #loop126 + alt126 = 2 + LA126_0 = self.input.LA(1) + + if (LA126_0 == STRING_LITERAL) : + alt126 = 1 + + + if alt126 == 1: + # C.g:0:0: STRING_LITERAL + self.match(self.input, STRING_LITERAL, self.FOLLOW_STRING_LITERAL_in_synpred1371668) + if self.failed: + return + + + else: + if cnt126 >= 1: + break #loop126 + + if self.backtracking > 0: + self.failed = True + return + + eee = EarlyExitException(126, self.input) + raise eee + + cnt126 += 1 + + + + + # $ANTLR end synpred137 + + + + # $ANTLR start synpred141 + def synpred141_fragment(self, ): + # C.g:405:4: ( lvalue assignment_operator assignment_expression ) + # C.g:405:4: lvalue assignment_operator assignment_expression + self.following.append(self.FOLLOW_lvalue_in_synpred1411729) + self.lvalue() + self.following.pop() + if self.failed: + return + self.following.append(self.FOLLOW_assignment_operator_in_synpred1411731) + self.assignment_operator() + self.following.pop() + if self.failed: + return + self.following.append(self.FOLLOW_assignment_expression_in_synpred1411733) + self.assignment_expression() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred141 + + + + # $ANTLR start synpred168 + def synpred168_fragment(self, ): + # C.g:467:4: ( expression_statement ) + # C.g:467:4: expression_statement + self.following.append(self.FOLLOW_expression_statement_in_synpred1682020) + self.expression_statement() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred168 + + + + # $ANTLR start synpred172 + def synpred172_fragment(self, ): + # C.g:471:4: ( macro_statement ) + # C.g:471:4: macro_statement + self.following.append(self.FOLLOW_macro_statement_in_synpred1722040) + self.macro_statement() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred172 + + + + # $ANTLR start synpred173 + def synpred173_fragment(self, ): + # C.g:472:4: ( asm2_statement ) + # C.g:472:4: asm2_statement + self.following.append(self.FOLLOW_asm2_statement_in_synpred1732045) + self.asm2_statement() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred173 + + + + # $ANTLR start synpred180 + def synpred180_fragment(self, ): + # C.g:491:19: ( declaration ) + # C.g:491:19: declaration + self.following.append(self.FOLLOW_declaration_in_synpred1802151) + self.declaration() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred180 + + + + # $ANTLR start synpred181 + def synpred181_fragment(self, ): + # C.g:491:33: ( statement_list ) + # C.g:491:33: statement_list + self.following.append(self.FOLLOW_statement_list_in_synpred1812155) + self.statement_list() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred181 + + + + # $ANTLR start synpred185 + def synpred185_fragment(self, ): + # C.g:501:8: ( declaration ) + # C.g:501:8: declaration + self.following.append(self.FOLLOW_declaration_in_synpred1852210) + self.declaration() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred185 + + + + # $ANTLR start synpred187 + def synpred187_fragment(self, ): + # C.g:505:4: ( statement ) + # C.g:505:4: statement + self.following.append(self.FOLLOW_statement_in_synpred1872227) + self.statement() + self.following.pop() + if self.failed: + return + + + # $ANTLR end synpred187 + + + + def synpred185(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred185_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred7(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred7_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred14(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred14_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred65(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred65_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred15(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred15_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred117(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred117_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred173(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred173_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred68(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred68_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred40(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred40_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred141(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred141_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred75(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred75_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred92(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred92_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred4(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred4_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred85(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred85_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred39(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred39_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred76(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred76_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred119(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred119_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred90(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred90_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred187(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred187_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred33(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred33_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred2(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred2_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred83(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred83_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred69(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred69_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred72(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred72_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred168(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred168_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred34(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred34_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred181(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred181_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred116(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred116_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred113(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred113_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred80(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred80_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred73(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred73_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred89(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred89_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred10(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred10_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred81(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred81_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred180(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred180_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred136(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred136_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred77(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred77_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred172(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred172_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred137(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred137_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred74(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred74_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred5(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred5_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred108(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred108_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred82(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred82_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred93(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred93_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + def synpred66(self): + self.backtracking += 1 + start = self.input.mark() + self.synpred66_fragment() + success = not self.failed + self.input.rewind(start) + self.backtracking -= 1 + self.failed = False + return success + + + + + + FOLLOW_external_declaration_in_translation_unit64 = frozenset([1, 4, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 65]) + FOLLOW_function_definition_in_external_declaration103 = frozenset([1]) + FOLLOW_declaration_in_external_declaration108 = frozenset([1]) + FOLLOW_macro_statement_in_external_declaration113 = frozenset([1, 25]) + FOLLOW_25_in_external_declaration116 = frozenset([1]) + FOLLOW_declaration_specifiers_in_function_definition147 = frozenset([4, 58, 59, 60, 61, 65]) + FOLLOW_declarator_in_function_definition150 = frozenset([4, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]) + FOLLOW_declaration_in_function_definition156 = frozenset([4, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]) + FOLLOW_compound_statement_in_function_definition161 = frozenset([1]) + FOLLOW_compound_statement_in_function_definition170 = frozenset([1]) + FOLLOW_26_in_declaration193 = frozenset([4, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 65]) + FOLLOW_declaration_specifiers_in_declaration197 = frozenset([4, 58, 59, 60, 61, 65]) + FOLLOW_init_declarator_list_in_declaration206 = frozenset([25]) + FOLLOW_25_in_declaration210 = frozenset([1]) + FOLLOW_declaration_specifiers_in_declaration224 = frozenset([4, 25, 58, 59, 60, 61, 65]) + FOLLOW_init_declarator_list_in_declaration228 = frozenset([25]) + FOLLOW_25_in_declaration233 = frozenset([1]) + FOLLOW_storage_class_specifier_in_declaration_specifiers254 = frozenset([1, 4, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]) + FOLLOW_type_specifier_in_declaration_specifiers262 = frozenset([1, 4, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]) + FOLLOW_type_qualifier_in_declaration_specifiers276 = frozenset([1, 4, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]) + FOLLOW_init_declarator_in_init_declarator_list298 = frozenset([1, 27]) + FOLLOW_27_in_init_declarator_list301 = frozenset([4, 58, 59, 60, 61, 65]) + FOLLOW_init_declarator_in_init_declarator_list303 = frozenset([1, 27]) + FOLLOW_declarator_in_init_declarator316 = frozenset([1, 28]) + FOLLOW_28_in_init_declarator319 = frozenset([4, 5, 6, 7, 8, 9, 10, 43, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_initializer_in_init_declarator321 = frozenset([1]) + FOLLOW_set_in_storage_class_specifier0 = frozenset([1]) + FOLLOW_34_in_type_specifier366 = frozenset([1]) + FOLLOW_35_in_type_specifier371 = frozenset([1]) + FOLLOW_36_in_type_specifier376 = frozenset([1]) + FOLLOW_37_in_type_specifier381 = frozenset([1]) + FOLLOW_38_in_type_specifier386 = frozenset([1]) + FOLLOW_39_in_type_specifier391 = frozenset([1]) + FOLLOW_40_in_type_specifier396 = frozenset([1]) + FOLLOW_41_in_type_specifier401 = frozenset([1]) + FOLLOW_42_in_type_specifier406 = frozenset([1]) + FOLLOW_struct_or_union_specifier_in_type_specifier413 = frozenset([1]) + FOLLOW_enum_specifier_in_type_specifier423 = frozenset([1]) + FOLLOW_type_id_in_type_specifier441 = frozenset([1]) + FOLLOW_IDENTIFIER_in_type_id457 = frozenset([1]) + FOLLOW_struct_or_union_in_struct_or_union_specifier484 = frozenset([4, 43]) + FOLLOW_IDENTIFIER_in_struct_or_union_specifier486 = frozenset([43]) + FOLLOW_43_in_struct_or_union_specifier489 = frozenset([4, 34, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]) + FOLLOW_struct_declaration_list_in_struct_or_union_specifier491 = frozenset([44]) + FOLLOW_44_in_struct_or_union_specifier493 = frozenset([1]) + FOLLOW_struct_or_union_in_struct_or_union_specifier498 = frozenset([4]) + FOLLOW_IDENTIFIER_in_struct_or_union_specifier500 = frozenset([1]) + FOLLOW_set_in_struct_or_union0 = frozenset([1]) + FOLLOW_struct_declaration_in_struct_declaration_list527 = frozenset([1, 4, 34, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]) + FOLLOW_specifier_qualifier_list_in_struct_declaration539 = frozenset([4, 47, 58, 59, 60, 61, 65]) + FOLLOW_struct_declarator_list_in_struct_declaration541 = frozenset([25]) + FOLLOW_25_in_struct_declaration543 = frozenset([1]) + FOLLOW_type_qualifier_in_specifier_qualifier_list556 = frozenset([1, 4, 34, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]) + FOLLOW_type_specifier_in_specifier_qualifier_list560 = frozenset([1, 4, 34, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]) + FOLLOW_struct_declarator_in_struct_declarator_list574 = frozenset([1, 27]) + FOLLOW_27_in_struct_declarator_list577 = frozenset([4, 47, 58, 59, 60, 61, 65]) + FOLLOW_struct_declarator_in_struct_declarator_list579 = frozenset([1, 27]) + FOLLOW_declarator_in_struct_declarator592 = frozenset([1, 47]) + FOLLOW_47_in_struct_declarator595 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_constant_expression_in_struct_declarator597 = frozenset([1]) + FOLLOW_47_in_struct_declarator604 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_constant_expression_in_struct_declarator606 = frozenset([1]) + FOLLOW_48_in_enum_specifier624 = frozenset([43]) + FOLLOW_43_in_enum_specifier626 = frozenset([4]) + FOLLOW_enumerator_list_in_enum_specifier628 = frozenset([27, 44]) + FOLLOW_27_in_enum_specifier630 = frozenset([44]) + FOLLOW_44_in_enum_specifier633 = frozenset([1]) + FOLLOW_48_in_enum_specifier638 = frozenset([4]) + FOLLOW_IDENTIFIER_in_enum_specifier640 = frozenset([43]) + FOLLOW_43_in_enum_specifier642 = frozenset([4]) + FOLLOW_enumerator_list_in_enum_specifier644 = frozenset([27, 44]) + FOLLOW_27_in_enum_specifier646 = frozenset([44]) + FOLLOW_44_in_enum_specifier649 = frozenset([1]) + FOLLOW_48_in_enum_specifier654 = frozenset([4]) + FOLLOW_IDENTIFIER_in_enum_specifier656 = frozenset([1]) + FOLLOW_enumerator_in_enumerator_list667 = frozenset([1, 27]) + FOLLOW_27_in_enumerator_list670 = frozenset([4]) + FOLLOW_enumerator_in_enumerator_list672 = frozenset([1, 27]) + FOLLOW_IDENTIFIER_in_enumerator685 = frozenset([1, 28]) + FOLLOW_28_in_enumerator688 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_constant_expression_in_enumerator690 = frozenset([1]) + FOLLOW_set_in_type_qualifier0 = frozenset([1]) + FOLLOW_pointer_in_declarator769 = frozenset([4, 58, 59, 60, 61]) + FOLLOW_58_in_declarator773 = frozenset([4, 59, 60, 61]) + FOLLOW_59_in_declarator778 = frozenset([4, 60, 61]) + FOLLOW_60_in_declarator783 = frozenset([4, 61]) + FOLLOW_direct_declarator_in_declarator787 = frozenset([1]) + FOLLOW_pointer_in_declarator793 = frozenset([1]) + FOLLOW_IDENTIFIER_in_direct_declarator804 = frozenset([1, 61, 63]) + FOLLOW_declarator_suffix_in_direct_declarator806 = frozenset([1, 61, 63]) + FOLLOW_61_in_direct_declarator812 = frozenset([4, 58, 59, 60, 61, 65]) + FOLLOW_58_in_direct_declarator815 = frozenset([4, 58, 59, 60, 61, 65]) + FOLLOW_declarator_in_direct_declarator819 = frozenset([62]) + FOLLOW_62_in_direct_declarator821 = frozenset([61, 63]) + FOLLOW_declarator_suffix_in_direct_declarator823 = frozenset([1, 61, 63]) + FOLLOW_63_in_declarator_suffix837 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_constant_expression_in_declarator_suffix839 = frozenset([64]) + FOLLOW_64_in_declarator_suffix841 = frozenset([1]) + FOLLOW_63_in_declarator_suffix851 = frozenset([64]) + FOLLOW_64_in_declarator_suffix853 = frozenset([1]) + FOLLOW_61_in_declarator_suffix863 = frozenset([4, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 65]) + FOLLOW_parameter_type_list_in_declarator_suffix865 = frozenset([62]) + FOLLOW_62_in_declarator_suffix867 = frozenset([1]) + FOLLOW_61_in_declarator_suffix877 = frozenset([4]) + FOLLOW_identifier_list_in_declarator_suffix879 = frozenset([62]) + FOLLOW_62_in_declarator_suffix881 = frozenset([1]) + FOLLOW_61_in_declarator_suffix891 = frozenset([62]) + FOLLOW_62_in_declarator_suffix893 = frozenset([1]) + FOLLOW_65_in_pointer904 = frozenset([49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]) + FOLLOW_type_qualifier_in_pointer906 = frozenset([1, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 65]) + FOLLOW_pointer_in_pointer909 = frozenset([1]) + FOLLOW_65_in_pointer915 = frozenset([65]) + FOLLOW_pointer_in_pointer917 = frozenset([1]) + FOLLOW_65_in_pointer922 = frozenset([1]) + FOLLOW_parameter_list_in_parameter_type_list933 = frozenset([1, 27]) + FOLLOW_27_in_parameter_type_list936 = frozenset([53, 66]) + FOLLOW_53_in_parameter_type_list939 = frozenset([66]) + FOLLOW_66_in_parameter_type_list943 = frozenset([1]) + FOLLOW_parameter_declaration_in_parameter_list956 = frozenset([1, 27]) + FOLLOW_27_in_parameter_list959 = frozenset([4, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 65]) + FOLLOW_53_in_parameter_list962 = frozenset([4, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 65]) + FOLLOW_parameter_declaration_in_parameter_list966 = frozenset([1, 27]) + FOLLOW_declaration_specifiers_in_parameter_declaration979 = frozenset([1, 4, 53, 58, 59, 60, 61, 63, 65]) + FOLLOW_declarator_in_parameter_declaration982 = frozenset([1, 4, 53, 58, 59, 60, 61, 63, 65]) + FOLLOW_abstract_declarator_in_parameter_declaration984 = frozenset([1, 4, 53, 58, 59, 60, 61, 63, 65]) + FOLLOW_53_in_parameter_declaration989 = frozenset([1]) + FOLLOW_pointer_in_parameter_declaration998 = frozenset([4, 65]) + FOLLOW_IDENTIFIER_in_parameter_declaration1001 = frozenset([1]) + FOLLOW_IDENTIFIER_in_identifier_list1012 = frozenset([1, 27]) + FOLLOW_27_in_identifier_list1016 = frozenset([4]) + FOLLOW_IDENTIFIER_in_identifier_list1018 = frozenset([1, 27]) + FOLLOW_specifier_qualifier_list_in_type_name1031 = frozenset([1, 61, 63, 65]) + FOLLOW_abstract_declarator_in_type_name1033 = frozenset([1]) + FOLLOW_type_id_in_type_name1039 = frozenset([1]) + FOLLOW_pointer_in_abstract_declarator1050 = frozenset([1, 61, 63]) + FOLLOW_direct_abstract_declarator_in_abstract_declarator1052 = frozenset([1]) + FOLLOW_direct_abstract_declarator_in_abstract_declarator1058 = frozenset([1]) + FOLLOW_61_in_direct_abstract_declarator1071 = frozenset([61, 63, 65]) + FOLLOW_abstract_declarator_in_direct_abstract_declarator1073 = frozenset([62]) + FOLLOW_62_in_direct_abstract_declarator1075 = frozenset([1, 61, 63]) + FOLLOW_abstract_declarator_suffix_in_direct_abstract_declarator1079 = frozenset([1, 61, 63]) + FOLLOW_abstract_declarator_suffix_in_direct_abstract_declarator1083 = frozenset([1, 61, 63]) + FOLLOW_63_in_abstract_declarator_suffix1095 = frozenset([64]) + FOLLOW_64_in_abstract_declarator_suffix1097 = frozenset([1]) + FOLLOW_63_in_abstract_declarator_suffix1102 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_constant_expression_in_abstract_declarator_suffix1104 = frozenset([64]) + FOLLOW_64_in_abstract_declarator_suffix1106 = frozenset([1]) + FOLLOW_61_in_abstract_declarator_suffix1111 = frozenset([62]) + FOLLOW_62_in_abstract_declarator_suffix1113 = frozenset([1]) + FOLLOW_61_in_abstract_declarator_suffix1118 = frozenset([4, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 65]) + FOLLOW_parameter_type_list_in_abstract_declarator_suffix1120 = frozenset([62]) + FOLLOW_62_in_abstract_declarator_suffix1122 = frozenset([1]) + FOLLOW_assignment_expression_in_initializer1135 = frozenset([1]) + FOLLOW_43_in_initializer1140 = frozenset([4, 5, 6, 7, 8, 9, 10, 43, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_initializer_list_in_initializer1142 = frozenset([27, 44]) + FOLLOW_27_in_initializer1144 = frozenset([44]) + FOLLOW_44_in_initializer1147 = frozenset([1]) + FOLLOW_initializer_in_initializer_list1158 = frozenset([1, 27]) + FOLLOW_27_in_initializer_list1161 = frozenset([4, 5, 6, 7, 8, 9, 10, 43, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_initializer_in_initializer_list1163 = frozenset([1, 27]) + FOLLOW_assignment_expression_in_argument_expression_list1181 = frozenset([1, 27, 53]) + FOLLOW_53_in_argument_expression_list1184 = frozenset([1, 27]) + FOLLOW_27_in_argument_expression_list1189 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_assignment_expression_in_argument_expression_list1191 = frozenset([1, 27, 53]) + FOLLOW_53_in_argument_expression_list1194 = frozenset([1, 27]) + FOLLOW_multiplicative_expression_in_additive_expression1210 = frozenset([1, 67, 68]) + FOLLOW_67_in_additive_expression1214 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_multiplicative_expression_in_additive_expression1216 = frozenset([1, 67, 68]) + FOLLOW_68_in_additive_expression1220 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_multiplicative_expression_in_additive_expression1222 = frozenset([1, 67, 68]) + FOLLOW_cast_expression_in_multiplicative_expression1236 = frozenset([1, 65, 69, 70]) + FOLLOW_65_in_multiplicative_expression1240 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_cast_expression_in_multiplicative_expression1242 = frozenset([1, 65, 69, 70]) + FOLLOW_69_in_multiplicative_expression1246 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_cast_expression_in_multiplicative_expression1248 = frozenset([1, 65, 69, 70]) + FOLLOW_70_in_multiplicative_expression1252 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_cast_expression_in_multiplicative_expression1254 = frozenset([1, 65, 69, 70]) + FOLLOW_61_in_cast_expression1267 = frozenset([4, 34, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]) + FOLLOW_type_name_in_cast_expression1269 = frozenset([62]) + FOLLOW_62_in_cast_expression1271 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_cast_expression_in_cast_expression1273 = frozenset([1]) + FOLLOW_unary_expression_in_cast_expression1278 = frozenset([1]) + FOLLOW_postfix_expression_in_unary_expression1289 = frozenset([1]) + FOLLOW_71_in_unary_expression1294 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_unary_expression_in_unary_expression1296 = frozenset([1]) + FOLLOW_72_in_unary_expression1301 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_unary_expression_in_unary_expression1303 = frozenset([1]) + FOLLOW_unary_operator_in_unary_expression1308 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_cast_expression_in_unary_expression1310 = frozenset([1]) + FOLLOW_73_in_unary_expression1315 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_unary_expression_in_unary_expression1317 = frozenset([1]) + FOLLOW_73_in_unary_expression1322 = frozenset([61]) + FOLLOW_61_in_unary_expression1324 = frozenset([4, 34, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]) + FOLLOW_type_name_in_unary_expression1326 = frozenset([62]) + FOLLOW_62_in_unary_expression1328 = frozenset([1]) + FOLLOW_primary_expression_in_postfix_expression1352 = frozenset([1, 61, 63, 65, 71, 72, 74, 75]) + FOLLOW_63_in_postfix_expression1368 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_expression_in_postfix_expression1370 = frozenset([64]) + FOLLOW_64_in_postfix_expression1372 = frozenset([1, 61, 63, 65, 71, 72, 74, 75]) + FOLLOW_61_in_postfix_expression1386 = frozenset([62]) + FOLLOW_62_in_postfix_expression1390 = frozenset([1, 61, 63, 65, 71, 72, 74, 75]) + FOLLOW_61_in_postfix_expression1405 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_argument_expression_list_in_postfix_expression1409 = frozenset([62]) + FOLLOW_62_in_postfix_expression1413 = frozenset([1, 61, 63, 65, 71, 72, 74, 75]) + FOLLOW_61_in_postfix_expression1429 = frozenset([4, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 65]) + FOLLOW_macro_parameter_list_in_postfix_expression1431 = frozenset([62]) + FOLLOW_62_in_postfix_expression1433 = frozenset([1, 61, 63, 65, 71, 72, 74, 75]) + FOLLOW_74_in_postfix_expression1447 = frozenset([4]) + FOLLOW_IDENTIFIER_in_postfix_expression1451 = frozenset([1, 61, 63, 65, 71, 72, 74, 75]) + FOLLOW_65_in_postfix_expression1467 = frozenset([4]) + FOLLOW_IDENTIFIER_in_postfix_expression1471 = frozenset([1, 61, 63, 65, 71, 72, 74, 75]) + FOLLOW_75_in_postfix_expression1487 = frozenset([4]) + FOLLOW_IDENTIFIER_in_postfix_expression1491 = frozenset([1, 61, 63, 65, 71, 72, 74, 75]) + FOLLOW_71_in_postfix_expression1507 = frozenset([1, 61, 63, 65, 71, 72, 74, 75]) + FOLLOW_72_in_postfix_expression1521 = frozenset([1, 61, 63, 65, 71, 72, 74, 75]) + FOLLOW_parameter_declaration_in_macro_parameter_list1544 = frozenset([1, 27]) + FOLLOW_27_in_macro_parameter_list1547 = frozenset([4, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 65]) + FOLLOW_parameter_declaration_in_macro_parameter_list1549 = frozenset([1, 27]) + FOLLOW_set_in_unary_operator0 = frozenset([1]) + FOLLOW_IDENTIFIER_in_primary_expression1598 = frozenset([1]) + FOLLOW_constant_in_primary_expression1603 = frozenset([1]) + FOLLOW_61_in_primary_expression1608 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_expression_in_primary_expression1610 = frozenset([62]) + FOLLOW_62_in_primary_expression1612 = frozenset([1]) + FOLLOW_HEX_LITERAL_in_constant1628 = frozenset([1]) + FOLLOW_OCTAL_LITERAL_in_constant1638 = frozenset([1]) + FOLLOW_DECIMAL_LITERAL_in_constant1648 = frozenset([1]) + FOLLOW_CHARACTER_LITERAL_in_constant1656 = frozenset([1]) + FOLLOW_IDENTIFIER_in_constant1665 = frozenset([4, 9]) + FOLLOW_STRING_LITERAL_in_constant1668 = frozenset([1, 4, 9]) + FOLLOW_IDENTIFIER_in_constant1673 = frozenset([1, 4]) + FOLLOW_FLOATING_POINT_LITERAL_in_constant1684 = frozenset([1]) + FOLLOW_assignment_expression_in_expression1700 = frozenset([1, 27]) + FOLLOW_27_in_expression1703 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_assignment_expression_in_expression1705 = frozenset([1, 27]) + FOLLOW_conditional_expression_in_constant_expression1718 = frozenset([1]) + FOLLOW_lvalue_in_assignment_expression1729 = frozenset([28, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88]) + FOLLOW_assignment_operator_in_assignment_expression1731 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_assignment_expression_in_assignment_expression1733 = frozenset([1]) + FOLLOW_conditional_expression_in_assignment_expression1738 = frozenset([1]) + FOLLOW_unary_expression_in_lvalue1750 = frozenset([1]) + FOLLOW_set_in_assignment_operator0 = frozenset([1]) + FOLLOW_logical_or_expression_in_conditional_expression1824 = frozenset([1, 89]) + FOLLOW_89_in_conditional_expression1827 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_expression_in_conditional_expression1829 = frozenset([47]) + FOLLOW_47_in_conditional_expression1831 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_conditional_expression_in_conditional_expression1833 = frozenset([1]) + FOLLOW_logical_and_expression_in_logical_or_expression1848 = frozenset([1, 90]) + FOLLOW_90_in_logical_or_expression1851 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_logical_and_expression_in_logical_or_expression1853 = frozenset([1, 90]) + FOLLOW_inclusive_or_expression_in_logical_and_expression1866 = frozenset([1, 91]) + FOLLOW_91_in_logical_and_expression1869 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_inclusive_or_expression_in_logical_and_expression1871 = frozenset([1, 91]) + FOLLOW_exclusive_or_expression_in_inclusive_or_expression1884 = frozenset([1, 92]) + FOLLOW_92_in_inclusive_or_expression1887 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_exclusive_or_expression_in_inclusive_or_expression1889 = frozenset([1, 92]) + FOLLOW_and_expression_in_exclusive_or_expression1902 = frozenset([1, 93]) + FOLLOW_93_in_exclusive_or_expression1905 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_and_expression_in_exclusive_or_expression1907 = frozenset([1, 93]) + FOLLOW_equality_expression_in_and_expression1920 = frozenset([1, 76]) + FOLLOW_76_in_and_expression1923 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_equality_expression_in_and_expression1925 = frozenset([1, 76]) + FOLLOW_relational_expression_in_equality_expression1937 = frozenset([1, 94, 95]) + FOLLOW_set_in_equality_expression1940 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_relational_expression_in_equality_expression1946 = frozenset([1, 94, 95]) + FOLLOW_shift_expression_in_relational_expression1960 = frozenset([1, 96, 97, 98, 99]) + FOLLOW_set_in_relational_expression1963 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_shift_expression_in_relational_expression1973 = frozenset([1, 96, 97, 98, 99]) + FOLLOW_additive_expression_in_shift_expression1986 = frozenset([1, 100, 101]) + FOLLOW_set_in_shift_expression1989 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_additive_expression_in_shift_expression1995 = frozenset([1, 100, 101]) + FOLLOW_labeled_statement_in_statement2010 = frozenset([1]) + FOLLOW_compound_statement_in_statement2015 = frozenset([1]) + FOLLOW_expression_statement_in_statement2020 = frozenset([1]) + FOLLOW_selection_statement_in_statement2025 = frozenset([1]) + FOLLOW_iteration_statement_in_statement2030 = frozenset([1]) + FOLLOW_jump_statement_in_statement2035 = frozenset([1]) + FOLLOW_macro_statement_in_statement2040 = frozenset([1]) + FOLLOW_asm2_statement_in_statement2045 = frozenset([1]) + FOLLOW_asm1_statement_in_statement2050 = frozenset([1]) + FOLLOW_asm_statement_in_statement2055 = frozenset([1]) + FOLLOW_declaration_in_statement2060 = frozenset([1]) + FOLLOW_102_in_asm2_statement2071 = frozenset([4]) + FOLLOW_IDENTIFIER_in_asm2_statement2074 = frozenset([61]) + FOLLOW_61_in_asm2_statement2076 = frozenset([4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116]) + FOLLOW_set_in_asm2_statement2079 = frozenset([4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116]) + FOLLOW_62_in_asm2_statement2086 = frozenset([25]) + FOLLOW_25_in_asm2_statement2088 = frozenset([1]) + FOLLOW_103_in_asm1_statement2100 = frozenset([43]) + FOLLOW_43_in_asm1_statement2102 = frozenset([4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116]) + FOLLOW_set_in_asm1_statement2105 = frozenset([4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116]) + FOLLOW_44_in_asm1_statement2112 = frozenset([1]) + FOLLOW_104_in_asm_statement2123 = frozenset([43]) + FOLLOW_43_in_asm_statement2125 = frozenset([4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116]) + FOLLOW_set_in_asm_statement2128 = frozenset([4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116]) + FOLLOW_44_in_asm_statement2135 = frozenset([1]) + FOLLOW_IDENTIFIER_in_macro_statement2147 = frozenset([61]) + FOLLOW_61_in_macro_statement2149 = frozenset([4, 5, 6, 7, 8, 9, 10, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 65, 67, 68, 71, 72, 73, 76, 77, 78, 102, 103, 104, 105, 106, 107, 109, 110, 111, 112, 113, 114, 115, 116]) + FOLLOW_declaration_in_macro_statement2151 = frozenset([4, 5, 6, 7, 8, 9, 10, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 65, 67, 68, 71, 72, 73, 76, 77, 78, 102, 103, 104, 105, 106, 107, 109, 110, 111, 112, 113, 114, 115, 116]) + FOLLOW_statement_list_in_macro_statement2155 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 62, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_expression_in_macro_statement2158 = frozenset([62]) + FOLLOW_62_in_macro_statement2161 = frozenset([1]) + FOLLOW_IDENTIFIER_in_labeled_statement2173 = frozenset([47]) + FOLLOW_47_in_labeled_statement2175 = frozenset([4, 5, 6, 7, 8, 9, 10, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78, 102, 103, 104, 105, 106, 107, 109, 110, 111, 112, 113, 114, 115, 116]) + FOLLOW_statement_in_labeled_statement2177 = frozenset([1]) + FOLLOW_105_in_labeled_statement2182 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_constant_expression_in_labeled_statement2184 = frozenset([47]) + FOLLOW_47_in_labeled_statement2186 = frozenset([4, 5, 6, 7, 8, 9, 10, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78, 102, 103, 104, 105, 106, 107, 109, 110, 111, 112, 113, 114, 115, 116]) + FOLLOW_statement_in_labeled_statement2188 = frozenset([1]) + FOLLOW_106_in_labeled_statement2193 = frozenset([47]) + FOLLOW_47_in_labeled_statement2195 = frozenset([4, 5, 6, 7, 8, 9, 10, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78, 102, 103, 104, 105, 106, 107, 109, 110, 111, 112, 113, 114, 115, 116]) + FOLLOW_statement_in_labeled_statement2197 = frozenset([1]) + FOLLOW_43_in_compound_statement2208 = frozenset([4, 5, 6, 7, 8, 9, 10, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78, 102, 103, 104, 105, 106, 107, 109, 110, 111, 112, 113, 114, 115, 116]) + FOLLOW_declaration_in_compound_statement2210 = frozenset([4, 5, 6, 7, 8, 9, 10, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78, 102, 103, 104, 105, 106, 107, 109, 110, 111, 112, 113, 114, 115, 116]) + FOLLOW_statement_list_in_compound_statement2213 = frozenset([44]) + FOLLOW_44_in_compound_statement2216 = frozenset([1]) + FOLLOW_statement_in_statement_list2227 = frozenset([1, 4, 5, 6, 7, 8, 9, 10, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78, 102, 103, 104, 105, 106, 107, 109, 110, 111, 112, 113, 114, 115, 116]) + FOLLOW_25_in_expression_statement2239 = frozenset([1]) + FOLLOW_expression_in_expression_statement2244 = frozenset([25]) + FOLLOW_25_in_expression_statement2246 = frozenset([1]) + FOLLOW_107_in_selection_statement2257 = frozenset([61]) + FOLLOW_61_in_selection_statement2259 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_expression_in_selection_statement2263 = frozenset([62]) + FOLLOW_62_in_selection_statement2265 = frozenset([4, 5, 6, 7, 8, 9, 10, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78, 102, 103, 104, 105, 106, 107, 109, 110, 111, 112, 113, 114, 115, 116]) + FOLLOW_statement_in_selection_statement2269 = frozenset([1, 108]) + FOLLOW_108_in_selection_statement2284 = frozenset([4, 5, 6, 7, 8, 9, 10, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78, 102, 103, 104, 105, 106, 107, 109, 110, 111, 112, 113, 114, 115, 116]) + FOLLOW_statement_in_selection_statement2286 = frozenset([1]) + FOLLOW_109_in_selection_statement2293 = frozenset([61]) + FOLLOW_61_in_selection_statement2295 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_expression_in_selection_statement2297 = frozenset([62]) + FOLLOW_62_in_selection_statement2299 = frozenset([4, 5, 6, 7, 8, 9, 10, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78, 102, 103, 104, 105, 106, 107, 109, 110, 111, 112, 113, 114, 115, 116]) + FOLLOW_statement_in_selection_statement2301 = frozenset([1]) + FOLLOW_110_in_iteration_statement2312 = frozenset([61]) + FOLLOW_61_in_iteration_statement2314 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_expression_in_iteration_statement2318 = frozenset([62]) + FOLLOW_62_in_iteration_statement2320 = frozenset([4, 5, 6, 7, 8, 9, 10, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78, 102, 103, 104, 105, 106, 107, 109, 110, 111, 112, 113, 114, 115, 116]) + FOLLOW_statement_in_iteration_statement2322 = frozenset([1]) + FOLLOW_111_in_iteration_statement2329 = frozenset([4, 5, 6, 7, 8, 9, 10, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78, 102, 103, 104, 105, 106, 107, 109, 110, 111, 112, 113, 114, 115, 116]) + FOLLOW_statement_in_iteration_statement2331 = frozenset([110]) + FOLLOW_110_in_iteration_statement2333 = frozenset([61]) + FOLLOW_61_in_iteration_statement2335 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_expression_in_iteration_statement2339 = frozenset([62]) + FOLLOW_62_in_iteration_statement2341 = frozenset([25]) + FOLLOW_25_in_iteration_statement2343 = frozenset([1]) + FOLLOW_112_in_iteration_statement2350 = frozenset([61]) + FOLLOW_61_in_iteration_statement2352 = frozenset([4, 5, 6, 7, 8, 9, 10, 25, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_expression_statement_in_iteration_statement2354 = frozenset([4, 5, 6, 7, 8, 9, 10, 25, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_expression_statement_in_iteration_statement2358 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 62, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_expression_in_iteration_statement2360 = frozenset([62]) + FOLLOW_62_in_iteration_statement2363 = frozenset([4, 5, 6, 7, 8, 9, 10, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78, 102, 103, 104, 105, 106, 107, 109, 110, 111, 112, 113, 114, 115, 116]) + FOLLOW_statement_in_iteration_statement2365 = frozenset([1]) + FOLLOW_113_in_jump_statement2378 = frozenset([4]) + FOLLOW_IDENTIFIER_in_jump_statement2380 = frozenset([25]) + FOLLOW_25_in_jump_statement2382 = frozenset([1]) + FOLLOW_114_in_jump_statement2387 = frozenset([25]) + FOLLOW_25_in_jump_statement2389 = frozenset([1]) + FOLLOW_115_in_jump_statement2394 = frozenset([25]) + FOLLOW_25_in_jump_statement2396 = frozenset([1]) + FOLLOW_116_in_jump_statement2401 = frozenset([25]) + FOLLOW_25_in_jump_statement2403 = frozenset([1]) + FOLLOW_116_in_jump_statement2408 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_expression_in_jump_statement2410 = frozenset([25]) + FOLLOW_25_in_jump_statement2412 = frozenset([1]) + FOLLOW_declaration_specifiers_in_synpred290 = frozenset([1]) + FOLLOW_declaration_specifiers_in_synpred490 = frozenset([4, 58, 59, 60, 61, 65]) + FOLLOW_declarator_in_synpred493 = frozenset([4, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]) + FOLLOW_declaration_in_synpred495 = frozenset([4, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]) + FOLLOW_43_in_synpred498 = frozenset([1]) + FOLLOW_declaration_in_synpred5108 = frozenset([1]) + FOLLOW_declaration_specifiers_in_synpred7147 = frozenset([1]) + FOLLOW_declaration_specifiers_in_synpred10197 = frozenset([1]) + FOLLOW_type_specifier_in_synpred14262 = frozenset([1]) + FOLLOW_type_qualifier_in_synpred15276 = frozenset([1]) + FOLLOW_type_qualifier_in_synpred33434 = frozenset([1]) + FOLLOW_IDENTIFIER_in_synpred34432 = frozenset([4, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 65]) + FOLLOW_type_qualifier_in_synpred34434 = frozenset([4, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 65]) + FOLLOW_declarator_in_synpred34437 = frozenset([1]) + FOLLOW_type_qualifier_in_synpred39556 = frozenset([1]) + FOLLOW_type_specifier_in_synpred40560 = frozenset([1]) + FOLLOW_pointer_in_synpred65769 = frozenset([4, 58, 59, 60, 61]) + FOLLOW_58_in_synpred65773 = frozenset([4, 59, 60, 61]) + FOLLOW_59_in_synpred65778 = frozenset([4, 60, 61]) + FOLLOW_60_in_synpred65783 = frozenset([4, 61]) + FOLLOW_direct_declarator_in_synpred65787 = frozenset([1]) + FOLLOW_declarator_suffix_in_synpred66806 = frozenset([1]) + FOLLOW_58_in_synpred68815 = frozenset([1]) + FOLLOW_declarator_suffix_in_synpred69823 = frozenset([1]) + FOLLOW_61_in_synpred72863 = frozenset([4, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 65]) + FOLLOW_parameter_type_list_in_synpred72865 = frozenset([62]) + FOLLOW_62_in_synpred72867 = frozenset([1]) + FOLLOW_61_in_synpred73877 = frozenset([4]) + FOLLOW_identifier_list_in_synpred73879 = frozenset([62]) + FOLLOW_62_in_synpred73881 = frozenset([1]) + FOLLOW_type_qualifier_in_synpred74906 = frozenset([1]) + FOLLOW_pointer_in_synpred75909 = frozenset([1]) + FOLLOW_65_in_synpred76904 = frozenset([49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]) + FOLLOW_type_qualifier_in_synpred76906 = frozenset([1, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 65]) + FOLLOW_pointer_in_synpred76909 = frozenset([1]) + FOLLOW_65_in_synpred77915 = frozenset([65]) + FOLLOW_pointer_in_synpred77917 = frozenset([1]) + FOLLOW_53_in_synpred80962 = frozenset([1]) + FOLLOW_27_in_synpred81959 = frozenset([4, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 65]) + FOLLOW_53_in_synpred81962 = frozenset([4, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 65]) + FOLLOW_parameter_declaration_in_synpred81966 = frozenset([1]) + FOLLOW_declarator_in_synpred82982 = frozenset([1]) + FOLLOW_abstract_declarator_in_synpred83984 = frozenset([1]) + FOLLOW_declaration_specifiers_in_synpred85979 = frozenset([1, 4, 53, 58, 59, 60, 61, 63, 65]) + FOLLOW_declarator_in_synpred85982 = frozenset([1, 4, 53, 58, 59, 60, 61, 63, 65]) + FOLLOW_abstract_declarator_in_synpred85984 = frozenset([1, 4, 53, 58, 59, 60, 61, 63, 65]) + FOLLOW_53_in_synpred85989 = frozenset([1]) + FOLLOW_specifier_qualifier_list_in_synpred891031 = frozenset([1, 61, 63, 65]) + FOLLOW_abstract_declarator_in_synpred891033 = frozenset([1]) + FOLLOW_direct_abstract_declarator_in_synpred901052 = frozenset([1]) + FOLLOW_61_in_synpred921071 = frozenset([61, 63, 65]) + FOLLOW_abstract_declarator_in_synpred921073 = frozenset([62]) + FOLLOW_62_in_synpred921075 = frozenset([1]) + FOLLOW_abstract_declarator_suffix_in_synpred931083 = frozenset([1]) + FOLLOW_61_in_synpred1081267 = frozenset([4, 34, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]) + FOLLOW_type_name_in_synpred1081269 = frozenset([62]) + FOLLOW_62_in_synpred1081271 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_cast_expression_in_synpred1081273 = frozenset([1]) + FOLLOW_73_in_synpred1131315 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_unary_expression_in_synpred1131317 = frozenset([1]) + FOLLOW_61_in_synpred1161405 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_argument_expression_list_in_synpred1161409 = frozenset([62]) + FOLLOW_62_in_synpred1161413 = frozenset([1]) + FOLLOW_61_in_synpred1171429 = frozenset([4, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 65]) + FOLLOW_macro_parameter_list_in_synpred1171431 = frozenset([62]) + FOLLOW_62_in_synpred1171433 = frozenset([1]) + FOLLOW_65_in_synpred1191467 = frozenset([4]) + FOLLOW_IDENTIFIER_in_synpred1191471 = frozenset([1]) + FOLLOW_STRING_LITERAL_in_synpred1361668 = frozenset([1]) + FOLLOW_IDENTIFIER_in_synpred1371665 = frozenset([4, 9]) + FOLLOW_STRING_LITERAL_in_synpred1371668 = frozenset([1, 9]) + FOLLOW_lvalue_in_synpred1411729 = frozenset([28, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88]) + FOLLOW_assignment_operator_in_synpred1411731 = frozenset([4, 5, 6, 7, 8, 9, 10, 61, 65, 67, 68, 71, 72, 73, 76, 77, 78]) + FOLLOW_assignment_expression_in_synpred1411733 = frozenset([1]) + FOLLOW_expression_statement_in_synpred1682020 = frozenset([1]) + FOLLOW_macro_statement_in_synpred1722040 = frozenset([1]) + FOLLOW_asm2_statement_in_synpred1732045 = frozenset([1]) + FOLLOW_declaration_in_synpred1802151 = frozenset([1]) + FOLLOW_statement_list_in_synpred1812155 = frozenset([1]) + FOLLOW_declaration_in_synpred1852210 = frozenset([1]) + FOLLOW_statement_in_synpred1872227 = frozenset([1]) + diff --git a/BaseTools/Source/Python/Ecc/Check.py b/BaseTools/Source/Python/Ecc/Check.py new file mode 100644 index 0000000000..c8bc54de3e --- /dev/null +++ b/BaseTools/Source/Python/Ecc/Check.py @@ -0,0 +1,865 @@ +## @file +# This file is used to define checkpoints used by ECC tool +# +# Copyright (c) 2008, 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 accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +import os +import re +from CommonDataClass.DataClass import * +from Common.DataType import SUP_MODULE_LIST_STRING, TAB_VALUE_SPLIT +from EccToolError import * +import EccGlobalData +import c + +## Check +# +# This class is to define checkpoints used by ECC tool +# +# @param object: Inherited from object class +# +class Check(object): + def __init__(self): + pass + + # Check all required checkpoints + def Check(self): + self.MetaDataFileCheck() + self.DoxygenCheck() + self.IncludeFileCheck() + self.PredicateExpressionCheck() + self.DeclAndDataTypeCheck() + self.FunctionLayoutCheck() + self.NamingConventionCheck() + + # C Function Layout Checking + def FunctionLayoutCheck(self): + self.FunctionLayoutCheckReturnType() + self.FunctionLayoutCheckModifier() + self.FunctionLayoutCheckName() + self.FunctionLayoutCheckPrototype() + self.FunctionLayoutCheckBody() + self.FunctionLayoutCheckLocalVariable() + + def WalkTree(self): + IgnoredPattern = c.GetIgnoredDirListPattern() + for Dirpath, Dirnames, Filenames in os.walk(EccGlobalData.gTarget): + for Dir in Dirnames: + Dirname = os.path.join(Dirpath, Dir) + if os.path.islink(Dirname): + Dirname = os.path.realpath(Dirname) + if os.path.isdir(Dirname): + # symlinks to directories are treated as directories + Dirnames.remove(Dir) + Dirnames.append(Dirname) + if IgnoredPattern.match(Dirpath.upper()): + continue + yield (Dirpath, Dirnames, Filenames) + + # Check whether return type exists and in the first line + def FunctionLayoutCheckReturnType(self): + if EccGlobalData.gConfig.CFunctionLayoutCheckReturnType == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking function layout return type ...") + + for Dirpath, Dirnames, Filenames in self.WalkTree(): + for F in Filenames: + if os.path.splitext(F)[1] in ('.c', '.h'): + FullName = os.path.join(Dirpath, F) + c.CheckFuncLayoutReturnType(FullName) + + # Check whether any optional functional modifiers exist and next to the return type + def FunctionLayoutCheckModifier(self): + if EccGlobalData.gConfig.CFunctionLayoutCheckOptionalFunctionalModifier == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking function layout modifier ...") + + for Dirpath, Dirnames, Filenames in self.WalkTree(): + for F in Filenames: + if os.path.splitext(F)[1] in ('.c', '.h'): + FullName = os.path.join(Dirpath, F) + c.CheckFuncLayoutModifier(FullName) + + # Check whether the next line contains the function name, left justified, followed by the beginning of the parameter list + # Check whether the closing parenthesis is on its own line and also indented two spaces + def FunctionLayoutCheckName(self): + if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionName == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking function layout function name ...") + + for Dirpath, Dirnames, Filenames in self.WalkTree(): + for F in Filenames: + if os.path.splitext(F)[1] in ('.c', '.h'): + FullName = os.path.join(Dirpath, F) + c.CheckFuncLayoutName(FullName) + # Check whether the function prototypes in include files have the same form as function definitions + def FunctionLayoutCheckPrototype(self): + if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionPrototype == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking function layout function prototype ...") + + for Dirpath, Dirnames, Filenames in self.WalkTree(): + for F in Filenames: + if os.path.splitext(F)[1] in ('.c'): + FullName = os.path.join(Dirpath, F) + EdkLogger.quiet("[PROTOTYPE]" + FullName) + c.CheckFuncLayoutPrototype(FullName) + + # Check whether the body of a function is contained by open and close braces that must be in the first column + def FunctionLayoutCheckBody(self): + if EccGlobalData.gConfig.CFunctionLayoutCheckFunctionBody == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking function layout function body ...") + + for Dirpath, Dirnames, Filenames in self.WalkTree(): + for F in Filenames: + if os.path.splitext(F)[1] in ('.c'): + FullName = os.path.join(Dirpath, F) + c.CheckFuncLayoutBody(FullName) + + # Check whether the data declarations is the first code in a module. + # self.CFunctionLayoutCheckDataDeclaration = 1 + # Check whether no initialization of a variable as part of its declaration + def FunctionLayoutCheckLocalVariable(self): + if EccGlobalData.gConfig.CFunctionLayoutCheckNoInitOfVariable == '1' or EccGlobalData.gConfig.CFunctionLayoutCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking function layout local variables ...") + + for Dirpath, Dirnames, Filenames in self.WalkTree(): + for F in Filenames: + if os.path.splitext(F)[1] in ('.c'): + FullName = os.path.join(Dirpath, F) + c.CheckFuncLayoutLocalVariable(FullName) + + # Check whether no use of STATIC for functions + # self.CFunctionLayoutCheckNoStatic = 1 + + # Declarations and Data Types Checking + def DeclAndDataTypeCheck(self): + self.DeclCheckNoUseCType() + self.DeclCheckInOutModifier() + self.DeclCheckEFIAPIModifier() + self.DeclCheckEnumeratedType() + self.DeclCheckStructureDeclaration() + self.DeclCheckSameStructure() + self.DeclCheckUnionType() + + + # Check whether no use of int, unsigned, char, void, static, long in any .c, .h or .asl files. + def DeclCheckNoUseCType(self): + if EccGlobalData.gConfig.DeclarationDataTypeCheckNoUseCType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking Declaration No use C type ...") + + for Dirpath, Dirnames, Filenames in self.WalkTree(): + for F in Filenames: + if os.path.splitext(F)[1] in ('.h', '.c'): + FullName = os.path.join(Dirpath, F) + c.CheckDeclNoUseCType(FullName) + + # Check whether the modifiers IN, OUT, OPTIONAL, and UNALIGNED are used only to qualify arguments to a function and should not appear in a data type declaration + def DeclCheckInOutModifier(self): + if EccGlobalData.gConfig.DeclarationDataTypeCheckInOutModifier == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking Declaration argument modifier ...") + + for Dirpath, Dirnames, Filenames in self.WalkTree(): + for F in Filenames: + if os.path.splitext(F)[1] in ('.h', '.c'): + FullName = os.path.join(Dirpath, F) + c.CheckDeclArgModifier(FullName) + + # Check whether the EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols + def DeclCheckEFIAPIModifier(self): + if EccGlobalData.gConfig.DeclarationDataTypeCheckEFIAPIModifier == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + pass + + # Check whether Enumerated Type has a 'typedef' and the name is capital + def DeclCheckEnumeratedType(self): + if EccGlobalData.gConfig.DeclarationDataTypeCheckEnumeratedType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking Declaration enum typedef ...") + + for Dirpath, Dirnames, Filenames in self.WalkTree(): + for F in Filenames: + if os.path.splitext(F)[1] in ('.h', '.c'): + FullName = os.path.join(Dirpath, F) + EdkLogger.quiet("[ENUM]" + FullName) + c.CheckDeclEnumTypedef(FullName) + + # Check whether Structure Type has a 'typedef' and the name is capital + def DeclCheckStructureDeclaration(self): + if EccGlobalData.gConfig.DeclarationDataTypeCheckStructureDeclaration == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking Declaration struct typedef ...") + + for Dirpath, Dirnames, Filenames in self.WalkTree(): + for F in Filenames: + if os.path.splitext(F)[1] in ('.h', '.c'): + FullName = os.path.join(Dirpath, F) + EdkLogger.quiet("[STRUCT]" + FullName) + c.CheckDeclStructTypedef(FullName) + + # Check whether having same Structure + def DeclCheckSameStructure(self): + if EccGlobalData.gConfig.DeclarationDataTypeCheckSameStructure == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking same struct ...") + AllStructure = {} + for IdentifierTable in EccGlobalData.gIdentifierTableList: + SqlCommand = """select ID, Name, BelongsToFile from %s where Model = %s""" %(IdentifierTable, MODEL_IDENTIFIER_STRUCTURE) + RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) + for Record in RecordSet: + if Record[1] != '': + if Record[1] not in AllStructure.keys(): + AllStructure[Record[1]] = Record[2] + else: + ID = AllStructure[Record[1]] + SqlCommand = """select FullPath from File where ID = %s """ % ID + NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) + OtherMsg = "The structure name '%s' is duplicate" % Record[1] + if NewRecordSet != []: + OtherMsg = "The structure name [%s] is duplicate with the one defined in %s, maybe struct NOT typedefed or the typedef new type NOT used to qualify variables" % (Record[1], NewRecordSet[0][0]) + if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE, Record[1]): + EccGlobalData.gDb.TblReport.Insert(ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE, OtherMsg = OtherMsg, BelongsToTable = IdentifierTable, BelongsToItem = Record[0]) + + # Check whether Union Type has a 'typedef' and the name is capital + def DeclCheckUnionType(self): + if EccGlobalData.gConfig.DeclarationDataTypeCheckUnionType == '1' or EccGlobalData.gConfig.DeclarationDataTypeCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking Declaration union typedef ...") + + for Dirpath, Dirnames, Filenames in self.WalkTree(): + for F in Filenames: + if os.path.splitext(F)[1] in ('.h', '.c'): + FullName = os.path.join(Dirpath, F) + EdkLogger.quiet("[UNION]" + FullName) + c.CheckDeclUnionTypedef(FullName) + + # Predicate Expression Checking + def PredicateExpressionCheck(self): + self.PredicateExpressionCheckBooleanValue() + self.PredicateExpressionCheckNonBooleanOperator() + self.PredicateExpressionCheckComparisonNullType() + + # Check whether Boolean values, variable type BOOLEAN not use explicit comparisons to TRUE or FALSE + def PredicateExpressionCheckBooleanValue(self): + if EccGlobalData.gConfig.PredicateExpressionCheckBooleanValue == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking predicate expression Boolean value ...") + + for Dirpath, Dirnames, Filenames in self.WalkTree(): + for F in Filenames: + if os.path.splitext(F)[1] in ('.c'): + FullName = os.path.join(Dirpath, F) + EdkLogger.quiet("[BOOLEAN]" + FullName) + c.CheckBooleanValueComparison(FullName) + + # Check whether Non-Boolean comparisons use a compare operator (==, !=, >, < >=, <=). + def PredicateExpressionCheckNonBooleanOperator(self): + if EccGlobalData.gConfig.PredicateExpressionCheckNonBooleanOperator == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking predicate expression Non-Boolean variable...") + + for Dirpath, Dirnames, Filenames in self.WalkTree(): + for F in Filenames: + if os.path.splitext(F)[1] in ('.c'): + FullName = os.path.join(Dirpath, F) + EdkLogger.quiet("[NON-BOOLEAN]" + FullName) + c.CheckNonBooleanValueComparison(FullName) + # Check whether a comparison of any pointer to zero must be done via the NULL type + def PredicateExpressionCheckComparisonNullType(self): + if EccGlobalData.gConfig.PredicateExpressionCheckComparisonNullType == '1' or EccGlobalData.gConfig.PredicateExpressionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking predicate expression NULL pointer ...") + + for Dirpath, Dirnames, Filenames in self.WalkTree(): + for F in Filenames: + if os.path.splitext(F)[1] in ('.c'): + FullName = os.path.join(Dirpath, F) + EdkLogger.quiet("[POINTER]" + FullName) + c.CheckPointerNullComparison(FullName) + # Include file checking + def IncludeFileCheck(self): + self.IncludeFileCheckIfndef() + self.IncludeFileCheckData() + self.IncludeFileCheckSameName() + + # Check whether having include files with same name + def IncludeFileCheckSameName(self): + if EccGlobalData.gConfig.IncludeFileCheckSameName == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking same header file name ...") + SqlCommand = """select ID, FullPath from File + where Model = 1002 order by Name """ + RecordDict = {} + RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) + for Record in RecordSet: + List = Record[1].replace('/', '\\').split('\\') + if len(List) >= 2: + Key = List[-2] + '\\' + List[-1] + else: + Key = List[0] + if Key not in RecordDict: + RecordDict[Key] = [Record] + else: + RecordDict[Key].append(Record) + + for Key in RecordDict: + if len(RecordDict[Key]) > 1: + for Item in RecordDict[Key]: + EccGlobalData.gDb.TblReport.Insert(ERROR_INCLUDE_FILE_CHECK_NAME, OtherMsg = "The file name for '%s' is duplicate" % (Item[1]), BelongsToTable = 'File', BelongsToItem = Item[0]) + + # Check whether all include file contents is guarded by a #ifndef statement. + def IncludeFileCheckIfndef(self): + if EccGlobalData.gConfig.IncludeFileCheckIfndefStatement == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking header file ifndef ...") + + for Dirpath, Dirnames, Filenames in self.WalkTree(): + for F in Filenames: + if os.path.splitext(F)[1] in ('.h'): + FullName = os.path.join(Dirpath, F) + MsgList = c.CheckHeaderFileIfndef(FullName) + + # Check whether include files NOT contain code or define data variables + def IncludeFileCheckData(self): + if EccGlobalData.gConfig.IncludeFileCheckData == '1' or EccGlobalData.gConfig.IncludeFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking header file data ...") + + for Dirpath, Dirnames, Filenames in self.WalkTree(): + for F in Filenames: + if os.path.splitext(F)[1] in ('.h'): + FullName = os.path.join(Dirpath, F) + MsgList = c.CheckHeaderFileData(FullName) + + # Doxygen document checking + def DoxygenCheck(self): + self.DoxygenCheckFileHeader() + self.DoxygenCheckFunctionHeader() + self.DoxygenCheckCommentDescription() + self.DoxygenCheckCommentFormat() + self.DoxygenCheckCommand() + + # Check whether the file headers are followed Doxygen special documentation blocks in section 2.3.5 + def DoxygenCheckFileHeader(self): + if EccGlobalData.gConfig.DoxygenCheckFileHeader == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking Doxygen file header ...") + + for Dirpath, Dirnames, Filenames in self.WalkTree(): + for F in Filenames: + if os.path.splitext(F)[1] in ('.h', '.c'): + FullName = os.path.join(Dirpath, F) + MsgList = c.CheckFileHeaderDoxygenComments(FullName) + + # Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5 + def DoxygenCheckFunctionHeader(self): + if EccGlobalData.gConfig.DoxygenCheckFunctionHeader == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking Doxygen function header ...") + + for Dirpath, Dirnames, Filenames in self.WalkTree(): + for F in Filenames: + if os.path.splitext(F)[1] in ('.h', '.c'): + FullName = os.path.join(Dirpath, F) + MsgList = c.CheckFuncHeaderDoxygenComments(FullName) + + # Check whether the first line of text in a comment block is a brief description of the element being documented. + # The brief description must end with a period. + def DoxygenCheckCommentDescription(self): + if EccGlobalData.gConfig.DoxygenCheckCommentDescription == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + pass + + # Check whether comment lines with '///< ... text ...' format, if it is used, it should be after the code section. + def DoxygenCheckCommentFormat(self): + if EccGlobalData.gConfig.DoxygenCheckCommentFormat == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking Doxygen comment ///< ...") + + for Dirpath, Dirnames, Filenames in self.WalkTree(): + for F in Filenames: + if os.path.splitext(F)[1] in ('.h', '.c'): + FullName = os.path.join(Dirpath, F) + MsgList = c.CheckDoxygenTripleForwardSlash(FullName) + + # Check whether only Doxygen commands allowed to mark the code are @bug and @todo. + def DoxygenCheckCommand(self): + if EccGlobalData.gConfig.DoxygenCheckCommand == '1' or EccGlobalData.gConfig.DoxygenCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking Doxygen command ...") + + for Dirpath, Dirnames, Filenames in self.WalkTree(): + for F in Filenames: + if os.path.splitext(F)[1] in ('.h', '.c'): + FullName = os.path.join(Dirpath, F) + MsgList = c.CheckDoxygenCommand(FullName) + + # Meta-Data File Processing Checking + def MetaDataFileCheck(self): + self.MetaDataFileCheckPathName() + self.MetaDataFileCheckGenerateFileList() + self.MetaDataFileCheckLibraryInstance() + self.MetaDataFileCheckLibraryInstanceDependent() + self.MetaDataFileCheckLibraryInstanceOrder() + self.MetaDataFileCheckLibraryNoUse() + self.MetaDataFileCheckBinaryInfInFdf() + self.MetaDataFileCheckPcdDuplicate() + self.MetaDataFileCheckPcdFlash() + self.MetaDataFileCheckPcdNoUse() + self.MetaDataFileCheckGuidDuplicate() + self.MetaDataFileCheckModuleFileNoUse() + self.MetaDataFileCheckPcdType() + + # Check whether each file defined in meta-data exists + def MetaDataFileCheckPathName(self): + if EccGlobalData.gConfig.MetaDataFileCheckPathName == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + # This item is covered when parsing Inf/Dec/Dsc files + pass + + # Generate a list for all files defined in meta-data files + def MetaDataFileCheckGenerateFileList(self): + if EccGlobalData.gConfig.MetaDataFileCheckGenerateFileList == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + # This item is covered when parsing Inf/Dec/Dsc files + pass + + # Check whether all Library Instances defined for a given module (or dependent library instance) match the module's type. + # Each Library Instance must specify the Supported Module Types in its Inf file, + # and any module specifying the library instance must be one of the supported types. + def MetaDataFileCheckLibraryInstance(self): + if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstance == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking for library instance type issue ...") + SqlCommand = """select A.ID, A.Value2, B.Value2 from Inf as A left join Inf as B + where A.Value1 = 'LIBRARY_CLASS' and A.Model = %s + and B.Value1 = 'MODULE_TYPE' and B.Model = %s and A.BelongsToFile = B.BelongsToFile + group by A.BelongsToFile""" % (MODEL_META_DATA_HEADER, MODEL_META_DATA_HEADER) + RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand) + LibraryClasses = {} + for Record in RecordSet: + List = Record[1].split('|', 1) + SupModType = [] + if len(List) == 1: + SupModType = SUP_MODULE_LIST_STRING.split(TAB_VALUE_SPLIT) + elif len(List) == 2: + SupModType = List[1].split() + + if List[0] not in LibraryClasses: + LibraryClasses[List[0]] = SupModType + else: + for Item in SupModType: + if Item not in LibraryClasses[List[0]]: + LibraryClasses[List[0]].append(Item) + + if Record[2] != 'BASE' and Record[2] not in SupModType: + EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_2, OtherMsg = "The Library Class '%s' does not specify its supported module types" % (List[0]), BelongsToTable = 'Inf', BelongsToItem = Record[0]) + + SqlCommand = """select A.ID, A.Value1, B.Value2 from Inf as A left join Inf as B + where A.Model = %s and B.Value1 = '%s' and B.Model = %s + and B.BelongsToFile = A.BelongsToFile""" \ + % (MODEL_EFI_LIBRARY_CLASS, 'MODULE_TYPE', MODEL_META_DATA_HEADER) + RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand) + # Merge all LibraryClasses' supmodlist + RecordDict = {} + for Record in RecordSet: + if Record[1] not in RecordDict: + RecordDict[Record[1]] = [str(Record[2])] + else: + if Record[2] not in RecordDict[Record[1]]: + RecordDict[Record[1]].append(Record[2]) + + for Record in RecordSet: + if Record[1] in LibraryClasses: + if Record[2] not in LibraryClasses[Record[1]] and 'BASE' not in RecordDict[Record[1]]: + if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, Record[1]): + EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, OtherMsg = "The type of Library Class [%s] defined in Inf file does not match the type of the module" % (Record[1]), BelongsToTable = 'Inf', BelongsToItem = Record[0]) + else: + if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, Record[1]): + EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, OtherMsg = "The type of Library Class [%s] defined in Inf file does not match the type of the module" % (Record[1]), BelongsToTable = 'Inf', BelongsToItem = Record[0]) + + # Check whether a Library Instance has been defined for all dependent library classes + def MetaDataFileCheckLibraryInstanceDependent(self): + if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstanceDependent == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking for library instance dependent issue ...") + SqlCommand = """select ID, Value1, Value2 from Dsc where Model = %s""" % MODEL_EFI_LIBRARY_CLASS + LibraryClasses = EccGlobalData.gDb.TblDsc.Exec(SqlCommand) + for LibraryClass in LibraryClasses: + if LibraryClass[1].upper() != 'NULL': + LibraryIns = os.path.normpath(os.path.join(EccGlobalData.gWorkspace, LibraryClass[2])) + SqlCommand = """select Value2 from Inf where BelongsToFile = + (select ID from File where lower(FullPath) = lower('%s')) + and Value1 = '%s'""" % (LibraryIns, 'LIBRARY_CLASS') + RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand) + IsFound = False + for Record in RecordSet: + LibName = Record[0].split('|', 1)[0] + if LibraryClass[1] == LibName: + IsFound = True + if not IsFound: + if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT, LibraryClass[1]): + EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT, OtherMsg = "The Library Class [%s] is not specified in '%s'" % (LibraryClass[1], LibraryClass[2]), BelongsToTable = 'Dsc', BelongsToItem = LibraryClass[0]) + + # Check whether the Library Instances specified by the LibraryClasses sections are listed in order of dependencies + def MetaDataFileCheckLibraryInstanceOrder(self): + if EccGlobalData.gConfig.MetaDataFileCheckLibraryInstanceOrder == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + # This checkpoint is not necessary for Ecc check + pass + + # Check whether the unnecessary inclusion of library classes in the Inf file + def MetaDataFileCheckLibraryNoUse(self): + if EccGlobalData.gConfig.MetaDataFileCheckLibraryNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking for library instance not used ...") + SqlCommand = """select ID, Value1 from Inf as A where A.Model = %s and A.Value1 not in (select B.Value1 from Dsc as B where Model = %s)""" % (MODEL_EFI_LIBRARY_CLASS, MODEL_EFI_LIBRARY_CLASS) + RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand) + for Record in RecordSet: + if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE, Record[1]): + EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE, OtherMsg = "The Library Class [%s] is not used in any platform" % (Record[1]), BelongsToTable = 'Inf', BelongsToItem = Record[0]) + + # Check whether an Inf file is specified in the FDF file, but not in the Dsc file, then the Inf file must be for a Binary module only + def MetaDataFileCheckBinaryInfInFdf(self): + if EccGlobalData.gConfig.MetaDataFileCheckBinaryInfInFdf == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking for non-binary modules defined in FDF files ...") + SqlCommand = """select A.ID, A.Value1 from Fdf as A + where A.Model = %s + and A.Enabled > -1 + and A.Value1 not in + (select B.Value1 from Dsc as B + where B.Model = %s + and B.Enabled > -1)""" % (MODEL_META_DATA_COMPONENT, MODEL_META_DATA_COMPONENT) + RecordSet = EccGlobalData.gDb.TblFdf.Exec(SqlCommand) + for Record in RecordSet: + FdfID = Record[0] + FilePath = Record[1] + FilePath = os.path.normpath(os.path.join(EccGlobalData.gWorkspace, FilePath)) + SqlCommand = """select ID from Inf where Model = %s and BelongsToFile = (select ID from File where FullPath like '%s') + """ % (MODEL_EFI_SOURCE_FILE, FilePath) + NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) + if NewRecordSet!= []: + if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF, FilePath): + EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF, OtherMsg = "File [%s] defined in FDF file and not in DSC file must be a binary module" % (FilePath), BelongsToTable = 'Fdf', BelongsToItem = FdfID) + + # Check whether a PCD is set in a Dsc file or the FDF file, but not in both. + def MetaDataFileCheckPcdDuplicate(self): + if EccGlobalData.gConfig.MetaDataFileCheckPcdDuplicate == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking for duplicate PCDs defined in both DSC and FDF files ...") + SqlCommand = """ + select A.ID, A.Value2, B.ID, B.Value2 from Dsc as A, Fdf as B + where A.Model >= %s and A.Model < %s + and B.Model >= %s and B.Model < %s + and A.Value2 = B.Value2 + and A.Enabled > -1 + and B.Enabled > -1 + group by A.ID + """% (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER) + RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand) + for Record in RecordSet: + if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[1]): + EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, OtherMsg = "The PCD [%s] is defined in both FDF file and DSC file" % (Record[1]), BelongsToTable = 'Dsc', BelongsToItem = Record[0]) + if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[3]): + EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, OtherMsg = "The PCD [%s] is defined in both FDF file and DSC file" % (Record[3]), BelongsToTable = 'Fdf', BelongsToItem = Record[2]) + + EdkLogger.quiet("Checking for duplicate PCDs defined in DEC files ...") + SqlCommand = """ + select A.ID, A.Value2 from Dec as A, Dec as B + where A.Model >= %s and A.Model < %s + and B.Model >= %s and B.Model < %s + and A.Value2 = B.Value2 + and ((A.Arch = B.Arch) and (A.Arch != 'COMMON' or B.Arch != 'COMMON')) + and A.ID != B.ID + and A.Enabled > -1 + and B.Enabled > -1 + and A.BelongsToFile = B.BelongsToFile + group by A.ID + """% (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER) + RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand) + for Record in RecordSet: + if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, Record[1]): + EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE, OtherMsg = "The PCD [%s] is defined duplicated in DEC file" % (Record[1]), BelongsToTable = 'Dec', BelongsToItem = Record[0]) + + # Check whether PCD settings in the FDF file can only be related to flash. + def MetaDataFileCheckPcdFlash(self): + if EccGlobalData.gConfig.MetaDataFileCheckPcdFlash == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking only Flash related PCDs are used in FDF ...") + SqlCommand = """ + select ID, Value2, BelongsToFile from Fdf as A + where A.Model >= %s and Model < %s + and A.Enabled > -1 + and A.Value2 not like '%%Flash%%' + """% (MODEL_PCD, MODEL_META_DATA_HEADER) + RecordSet = EccGlobalData.gDb.TblFdf.Exec(SqlCommand) + for Record in RecordSet: + if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_FLASH, Record[1]): + EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_FLASH, OtherMsg = "The PCD [%s] defined in FDF file is not related to Flash" % (Record[1]), BelongsToTable = 'Fdf', BelongsToItem = Record[0]) + + # Check whether PCDs used in Inf files but not specified in Dsc or FDF files + def MetaDataFileCheckPcdNoUse(self): + if EccGlobalData.gConfig.MetaDataFileCheckPcdNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking for non-specified PCDs ...") + SqlCommand = """ + select ID, Value2, BelongsToFile from Inf as A + where A.Model >= %s and Model < %s + and A.Enabled > -1 + and A.Value2 not in + (select Value2 from Dsc as B + where B.Model >= %s and B.Model < %s + and B.Enabled > -1) + and A.Value2 not in + (select Value2 from Fdf as C + where C.Model >= %s and C.Model < %s + and C.Enabled > -1) + """% (MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER, MODEL_PCD, MODEL_META_DATA_HEADER) + RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand) + for Record in RecordSet: + if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE, Record[1]): + EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_NO_USE, OtherMsg = "The PCD [%s] defined in INF file is not specified in either DSC or FDF files" % (Record[1]), BelongsToTable = 'Inf', BelongsToItem = Record[0]) + + # Check whether having duplicate guids defined for Guid/Protocol/Ppi + def MetaDataFileCheckGuidDuplicate(self): + if EccGlobalData.gConfig.MetaDataFileCheckGuidDuplicate == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking for duplicate GUID/PPI/PROTOCOL ...") + # Check Guid + self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID, EccGlobalData.gDb.TblDec) + self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID, EccGlobalData.gDb.TblDsc) + self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID, MODEL_EFI_GUID) + # Check protocol + self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL, EccGlobalData.gDb.TblDec) + self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL, EccGlobalData.gDb.TblDsc) + self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL, MODEL_EFI_PROTOCOL) + # Check ppi + self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI, EccGlobalData.gDb.TblDec) + self.CheckGuidProtocolPpi(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI, EccGlobalData.gDb.TblDsc) + self.CheckGuidProtocolPpiValue(ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI, MODEL_EFI_PPI) + + # Check whether all files under module directory are described in INF files + def MetaDataFileCheckModuleFileNoUse(self): + if EccGlobalData.gConfig.MetaDataFileCheckModuleFileNoUse == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking for no used module files ...") + SqlCommand = """ + select upper(Path) from File where ID in (select BelongsToFile from INF where BelongsToFile != -1) + """ + InfPathSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand) + InfPathList = [] + for Item in InfPathSet: + if Item[0] not in InfPathList: + InfPathList.append(Item[0]) + SqlCommand = """ + select ID, Path, FullPath from File where upper(FullPath) not in + (select upper(A.Path) || '\\' || upper(B.Value1) from File as A, INF as B + where A.ID in (select BelongsToFile from INF where Model = %s group by BelongsToFile) and + B.BelongsToFile = A.ID and B.Model = %s) + and (Model = %s or Model = %s) + """ % (MODEL_EFI_SOURCE_FILE, MODEL_EFI_SOURCE_FILE, MODEL_FILE_C, MODEL_FILE_H) + RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand) + for Record in RecordSet: + Path = Record[1] + Path = Path.upper().replace('\X64', '').replace('\IA32', '').replace('\EBC', '').replace('\IPF', '').replace('\ARM', '') + if Path in InfPathList: + if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE, Record[2]): + EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE, OtherMsg = "The source file [%s] is existing in module directory but it is not described in INF file." % (Record[2]), BelongsToTable = 'File', BelongsToItem = Record[0]) + + # Check whether the PCD is correctly used in C function via its type + def MetaDataFileCheckPcdType(self): + if EccGlobalData.gConfig.MetaDataFileCheckPcdType == '1' or EccGlobalData.gConfig.MetaDataFileCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking for pcd type in c code function usage ...") + SqlCommand = """ + select ID, Model, Value1, BelongsToFile from INF where Model > %s and Model < %s + """ % (MODEL_PCD, MODEL_META_DATA_HEADER) + PcdSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand) + for Pcd in PcdSet: + Model = Pcd[1] + PcdName = Pcd[2] + if len(Pcd[2].split(".")) > 1: + PcdName = Pcd[2].split(".")[1] + BelongsToFile = Pcd[3] + SqlCommand = """ + select ID from File where FullPath in + (select B.Path || '\\' || A.Value1 from INF as A, File as B where A.Model = %s and A.BelongsToFile = %s + and B.ID = %s) + """ %(MODEL_EFI_SOURCE_FILE, BelongsToFile, BelongsToFile) + TableSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) + for Tbl in TableSet: + TblName = 'Identifier' + str(Tbl[0]) + SqlCommand = """ + select Name, ID from %s where value like '%%%s%%' and Model = %s + """ % (TblName, PcdName, MODEL_IDENTIFIER_FUNCTION_CALLING) + RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand) + TblNumber = TblName.replace('Identifier', '') + for Record in RecordSet: + FunName = Record[0] + if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, FunName): + if Model in [MODEL_PCD_FIXED_AT_BUILD] and not FunName.startswith('FixedPcdGet'): + EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, OtherMsg = "The pcd '%s' is defined as a FixPcd but now it is called by c function [%s]" % (PcdName, FunName), BelongsToTable = TblName, BelongsToItem = Record[1]) + if Model in [MODEL_PCD_FEATURE_FLAG] and (not FunName.startswith('FeaturePcdGet') and not FunName.startswith('FeaturePcdSet')): + EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, OtherMsg = "The pcd '%s' is defined as a FeaturePcd but now it is called by c function [%s]" % (PcdName, FunName), BelongsToTable = TblName, BelongsToItem = Record[1]) + if Model in [MODEL_PCD_PATCHABLE_IN_MODULE] and (not FunName.startswith('PatchablePcdGet') and not FunName.startswith('PatchablePcdSet')): + EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_PCD_TYPE, OtherMsg = "The pcd '%s' is defined as a PatchablePcd but now it is called by c function [%s]" % (PcdName, FunName), BelongsToTable = TblName, BelongsToItem = Record[1]) + + #ERROR_META_DATA_FILE_CHECK_PCD_TYPE + pass + + # Check whether these is duplicate Guid/Ppi/Protocol name + def CheckGuidProtocolPpi(self, ErrorID, Model, Table): + Name = '' + if Model == MODEL_EFI_GUID: + Name = 'guid' + if Model == MODEL_EFI_PROTOCOL: + Name = 'protocol' + if Model == MODEL_EFI_PPI: + Name = 'ppi' + SqlCommand = """ + select A.ID, A.Value1 from %s as A, %s as B + where A.Model = %s and B.Model = %s + and A.Value1 = B.Value1 and A.ID <> B.ID + and A.Enabled > -1 + and B.Enabled > -1 + group by A.ID + """ % (Table.Table, Table.Table, Model, Model) + RecordSet = Table.Exec(SqlCommand) + for Record in RecordSet: + if not EccGlobalData.gException.IsException(ErrorID, Record[1]): + EccGlobalData.gDb.TblReport.Insert(ErrorID, OtherMsg = "The %s name [%s] is defined more than one time" % (Name.upper(), Record[1]), BelongsToTable = Table.Table, BelongsToItem = Record[0]) + + # Check whether these is duplicate Guid/Ppi/Protocol value + def CheckGuidProtocolPpiValue(self, ErrorID, Model): + Name = '' + Table = EccGlobalData.gDb.TblDec + if Model == MODEL_EFI_GUID: + Name = 'guid' + if Model == MODEL_EFI_PROTOCOL: + Name = 'protocol' + if Model == MODEL_EFI_PPI: + Name = 'ppi' + SqlCommand = """ + select A.ID, A.Value2 from %s as A, %s as B + where A.Model = %s and B.Model = %s + and A.Value2 = B.Value2 and A.ID <> B.ID + group by A.ID + """ % (Table.Table, Table.Table, Model, Model) + RecordSet = Table.Exec(SqlCommand) + for Record in RecordSet: + if not EccGlobalData.gException.IsException(ErrorID, Record[1]): + EccGlobalData.gDb.TblReport.Insert(ErrorID, OtherMsg = "The %s value [%s] is used more than one time" % (Name.upper(), Record[1]), BelongsToTable = Table.Table, BelongsToItem = Record[0]) + + # Naming Convention Check + def NamingConventionCheck(self): + + for Dirpath, Dirnames, Filenames in self.WalkTree(): + for F in Filenames: + if os.path.splitext(F)[1] in ('.h', '.c'): + FullName = os.path.join(Dirpath, F) + Id = c.GetTableID(FullName) + if Id < 0: + continue + FileTable = 'Identifier' + str(Id) + self.NamingConventionCheckDefineStatement(FileTable) + self.NamingConventionCheckTypedefStatement(FileTable) + self.NamingConventionCheckIfndefStatement(FileTable) + self.NamingConventionCheckVariableName(FileTable) + self.NamingConventionCheckSingleCharacterVariable(FileTable) + + self.NamingConventionCheckPathName() + self.NamingConventionCheckFunctionName() + + # Check whether only capital letters are used for #define declarations + def NamingConventionCheckDefineStatement(self, FileTable): + if EccGlobalData.gConfig.NamingConventionCheckDefineStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking naming covention of #define statement ...") + + SqlCommand = """select ID, Value from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_MACRO_DEFINE) + RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) + for Record in RecordSet: + Name = Record[1].strip().split()[1] + if Name.find('(') != -1: + Name = Name[0:Name.find('(')] + if Name.upper() != Name: + if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT, Name): + EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT, OtherMsg = "The #define name [%s] does not follow the rules" % (Name), BelongsToTable = FileTable, BelongsToItem = Record[0]) + + # Check whether only capital letters are used for typedef declarations + def NamingConventionCheckTypedefStatement(self, FileTable): + if EccGlobalData.gConfig.NamingConventionCheckTypedefStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking naming covention of #typedef statement ...") + + SqlCommand = """select ID, Name from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_TYPEDEF) + RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) + for Record in RecordSet: + Name = Record[1].strip() + if Name != '' and Name != None: + if Name[0] == '(': + Name = Name[1:Name.find(')')] + if Name.find('(') > -1: + Name = Name[Name.find('(') + 1 : Name.find(')')] + Name = Name.replace('WINAPI', '') + Name = Name.replace('*', '').strip() + if Name.upper() != Name: + if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT, Name): + EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT, OtherMsg = "The #typedef name [%s] does not follow the rules" % (Name), BelongsToTable = FileTable, BelongsToItem = Record[0]) + + # Check whether the #ifndef at the start of an include file uses both prefix and postfix underscore characters, '_'. + def NamingConventionCheckIfndefStatement(self, FileTable): + if EccGlobalData.gConfig.NamingConventionCheckTypedefStatement == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking naming covention of #ifndef statement ...") + + SqlCommand = """select ID, Value from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_MACRO_IFNDEF) + RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) + for Record in RecordSet: + Name = Record[1].replace('#ifndef', '').strip() + if Name[0] != '_' or Name[-1] != '_': + if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT, Name): + EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT, OtherMsg = "The #ifndef name [%s] does not follow the rules" % (Name), BelongsToTable = FileTable, BelongsToItem = Record[0]) + + # Rule for path name, variable name and function name + # 1. First character should be upper case + # 2. Existing lower case in a word + # 3. No space existence + # Check whether the path name followed the rule + def NamingConventionCheckPathName(self): + if EccGlobalData.gConfig.NamingConventionCheckPathName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking naming covention of file path name ...") + Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$') + SqlCommand = """select ID, Name from File""" + RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) + for Record in RecordSet: + if not Pattern.match(Record[1]): + if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_PATH_NAME, Record[1]): + EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_PATH_NAME, OtherMsg = "The file path [%s] does not follow the rules" % (Record[1]), BelongsToTable = 'File', BelongsToItem = Record[0]) + + # Rule for path name, variable name and function name + # 1. First character should be upper case + # 2. Existing lower case in a word + # 3. No space existence + # 4. Global variable name must start with a 'g' + # Check whether the variable name followed the rule + def NamingConventionCheckVariableName(self, FileTable): + if EccGlobalData.gConfig.NamingConventionCheckVariableName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking naming covention of variable name ...") + Pattern = re.compile(r'^[A-Zgm]+\S*[a-z]\S*$') + + SqlCommand = """select ID, Name from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_VARIABLE) + RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) + for Record in RecordSet: + if not Pattern.match(Record[1]): + if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Record[1]): + EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, OtherMsg = "The variable name [%s] does not follow the rules" % (Record[1]), BelongsToTable = FileTable, BelongsToItem = Record[0]) + + # Rule for path name, variable name and function name + # 1. First character should be upper case + # 2. Existing lower case in a word + # 3. No space existence + # Check whether the function name followed the rule + def NamingConventionCheckFunctionName(self): + if EccGlobalData.gConfig.NamingConventionCheckFunctionName == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking naming covention of function name ...") + Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$') + SqlCommand = """select ID, Name from Function""" + RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) + for Record in RecordSet: + if not Pattern.match(Record[1]): + if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME, Record[1]): + EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME, OtherMsg = "The function name [%s] does not follow the rules" % (Record[1]), BelongsToTable = 'Function', BelongsToItem = Record[0]) + + # Check whether NO use short variable name with single character + def NamingConventionCheckSingleCharacterVariable(self, FileTable): + if EccGlobalData.gConfig.NamingConventionCheckSingleCharacterVariable == '1' or EccGlobalData.gConfig.NamingConventionCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1': + EdkLogger.quiet("Checking naming covention of single character variable name ...") + + SqlCommand = """select ID, Name from %s where Model = %s""" %(FileTable, MODEL_IDENTIFIER_VARIABLE) + RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) + for Record in RecordSet: + Variable = Record[1].replace('*', '') + if len(Variable) == 1: + if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE, Record[1]): + EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE, OtherMsg = "The variable name [%s] does not follow the rules" % (Record[1]), BelongsToTable = FileTable, BelongsToItem = Record[0]) + +## +# +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +# +if __name__ == '__main__': + Check = Check() + Check.Check() diff --git a/BaseTools/Source/Python/Ecc/CodeFragment.py b/BaseTools/Source/Python/Ecc/CodeFragment.py new file mode 100644 index 0000000000..1c5c5e4df2 --- /dev/null +++ b/BaseTools/Source/Python/Ecc/CodeFragment.py @@ -0,0 +1,165 @@ +## @file +# fragments of source file +# +# Copyright (c) 2007, 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 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. +# + + +## The description of comment contents and start & end position +# +# +class Comment : + ## The constructor + # + # @param self The object pointer + # @param Str The message to record + # @param Begin The start position tuple. + # @param End The end position tuple. + # @param CommentType The type of comment (T_COMMENT_TWO_SLASH or T_COMMENT_SLASH_STAR). + # + def __init__(self, Str, Begin, End, CommentType): + self.Content = Str + self.StartPos = Begin + self.EndPos = End + self.Type = CommentType + +## The description of preprocess directives and start & end position +# +# +class PP_Directive : + ## The constructor + # + # @param self The object pointer + # @param Str The message to record + # @param Begin The start position tuple. + # @param End The end position tuple. + # + def __init__(self, Str, Begin, End): + self.Content = Str + self.StartPos = Begin + self.EndPos = End + +## The description of predicate expression and start & end position +# +# +class PredicateExpression : + ## The constructor + # + # @param self The object pointer + # @param Str The message to record + # @param Begin The start position tuple. + # @param End The end position tuple. + # + def __init__(self, Str, Begin, End): + self.Content = Str + self.StartPos = Begin + self.EndPos = End + +## The description of function definition and start & end position +# +# +class FunctionDefinition : + ## The constructor + # + # @param self The object pointer + # @param Str The message to record + # @param Begin The start position tuple. + # @param End The end position tuple. + # @param LBPos The left brace position tuple. + # + def __init__(self, ModifierStr, DeclStr, Begin, End, LBPos, NamePos): + self.Modifier = ModifierStr + self.Declarator = DeclStr + self.StartPos = Begin + self.EndPos = End + self.LeftBracePos = LBPos + self.NamePos = NamePos + +## The description of variable declaration and start & end position +# +# +class VariableDeclaration : + ## The constructor + # + # @param self The object pointer + # @param Str The message to record + # @param Begin The start position tuple. + # @param NamePos The name position tuple. + # + def __init__(self, ModifierStr, DeclStr, Begin, NamePos): + self.Modifier = ModifierStr + self.Declarator = DeclStr + self.StartPos = Begin + self.NameStartPos = NamePos + +## The description of enum definition and start & end position +# +# +class EnumerationDefinition : + ## The constructor + # + # @param self The object pointer + # @param Str The message to record + # @param Begin The start position tuple. + # @param End The end position tuple. + # + def __init__(self, Str, Begin, End): + self.Content = Str + self.StartPos = Begin + self.EndPos = End + +## The description of struct/union definition and start & end position +# +# +class StructUnionDefinition : + ## The constructor + # + # @param self The object pointer + # @param Str The message to record + # @param Begin The start position tuple. + # @param End The end position tuple. + # + def __init__(self, Str, Begin, End): + self.Content = Str + self.StartPos = Begin + self.EndPos = End + +## The description of 'Typedef' definition and start & end position +# +# +class TypedefDefinition : + ## The constructor + # + # @param self The object pointer + # @param Str The message to record + # @param Begin The start position tuple. + # @param End The end position tuple. + # + def __init__(self, FromStr, ToStr, Begin, End): + self.FromType = FromStr + self.ToType = ToStr + self.StartPos = Begin + self.EndPos = End + +class FunctionCalling: + ## The constructor + # + # @param self The object pointer + # @param Str The message to record + # @param Begin The start position tuple. + # @param End The end position tuple. + # + def __init__(self, Name, Param, Begin, End): + self.FuncName = Name + self.ParamList = Param + self.StartPos = Begin + self.EndPos = End + \ No newline at end of file diff --git a/BaseTools/Source/Python/Ecc/CodeFragmentCollector.py b/BaseTools/Source/Python/Ecc/CodeFragmentCollector.py new file mode 100644 index 0000000000..d95faeef6a --- /dev/null +++ b/BaseTools/Source/Python/Ecc/CodeFragmentCollector.py @@ -0,0 +1,624 @@ +## @file +# preprocess source file +# +# Copyright (c) 2007, 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 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 re +import os +import sys + +import antlr3 +from CLexer import CLexer +from CParser import CParser + +import FileProfile +from CodeFragment import Comment +from CodeFragment import PP_Directive +from ParserWarning import Warning + + +##define T_CHAR_SPACE ' ' +##define T_CHAR_NULL '\0' +##define T_CHAR_CR '\r' +##define T_CHAR_TAB '\t' +##define T_CHAR_LF '\n' +##define T_CHAR_SLASH '/' +##define T_CHAR_BACKSLASH '\\' +##define T_CHAR_DOUBLE_QUOTE '\"' +##define T_CHAR_SINGLE_QUOTE '\'' +##define T_CHAR_STAR '*' +##define T_CHAR_HASH '#' + +(T_CHAR_SPACE, T_CHAR_NULL, T_CHAR_CR, T_CHAR_TAB, T_CHAR_LF, T_CHAR_SLASH, \ +T_CHAR_BACKSLASH, T_CHAR_DOUBLE_QUOTE, T_CHAR_SINGLE_QUOTE, T_CHAR_STAR, T_CHAR_HASH) = \ +(' ', '\0', '\r', '\t', '\n', '/', '\\', '\"', '\'', '*', '#') + +SEPERATOR_TUPLE = ('=', '|', ',', '{', '}') + +(T_COMMENT_TWO_SLASH, T_COMMENT_SLASH_STAR) = (0, 1) + +(T_PP_INCLUDE, T_PP_DEFINE, T_PP_OTHERS) = (0, 1, 2) + +## The collector for source code fragments. +# +# PreprocessFile method should be called prior to ParseFile +# +# GetNext*** procedures mean these procedures will get next token first, then make judgement. +# Get*** procedures mean these procedures will make judgement on current token only. +# +class CodeFragmentCollector: + ## The constructor + # + # @param self The object pointer + # @param FileName The file that to be parsed + # + def __init__(self, FileName): + self.Profile = FileProfile.FileProfile(FileName) + self.Profile.FileLinesList.append(T_CHAR_LF) + self.FileName = FileName + self.CurrentLineNumber = 1 + self.CurrentOffsetWithinLine = 0 + + self.__Token = "" + self.__SkippedChars = "" + + ## __IsWhiteSpace() method + # + # Whether char at current FileBufferPos is whitespace + # + # @param self The object pointer + # @param Char The char to test + # @retval True The char is a kind of white space + # @retval False The char is NOT a kind of white space + # + def __IsWhiteSpace(self, Char): + if Char in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_SPACE, T_CHAR_TAB, T_CHAR_LF): + return True + else: + return False + + ## __SkipWhiteSpace() method + # + # Skip white spaces from current char, return number of chars skipped + # + # @param self The object pointer + # @retval Count The number of chars skipped + # + def __SkipWhiteSpace(self): + Count = 0 + while not self.__EndOfFile(): + Count += 1 + if self.__CurrentChar() in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_LF, T_CHAR_SPACE, T_CHAR_TAB): + self.__SkippedChars += str(self.__CurrentChar()) + self.__GetOneChar() + + else: + Count = Count - 1 + return Count + + ## __EndOfFile() method + # + # Judge current buffer pos is at file end + # + # @param self The object pointer + # @retval True Current File buffer position is at file end + # @retval False Current File buffer position is NOT at file end + # + def __EndOfFile(self): + NumberOfLines = len(self.Profile.FileLinesList) + SizeOfLastLine = NumberOfLines + if NumberOfLines > 0: + SizeOfLastLine = len(self.Profile.FileLinesList[-1]) + + if self.CurrentLineNumber == NumberOfLines and self.CurrentOffsetWithinLine >= SizeOfLastLine - 1: + return True + elif self.CurrentLineNumber > NumberOfLines: + return True + else: + return False + + ## __EndOfLine() method + # + # Judge current buffer pos is at line end + # + # @param self The object pointer + # @retval True Current File buffer position is at line end + # @retval False Current File buffer position is NOT at line end + # + def __EndOfLine(self): + SizeOfCurrentLine = len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) + if self.CurrentOffsetWithinLine >= SizeOfCurrentLine - 1: + return True + else: + return False + + ## Rewind() method + # + # Reset file data buffer to the initial state + # + # @param self The object pointer + # + def Rewind(self): + self.CurrentLineNumber = 1 + self.CurrentOffsetWithinLine = 0 + + ## __UndoOneChar() method + # + # Go back one char in the file buffer + # + # @param self The object pointer + # @retval True Successfully go back one char + # @retval False Not able to go back one char as file beginning reached + # + def __UndoOneChar(self): + + if self.CurrentLineNumber == 1 and self.CurrentOffsetWithinLine == 0: + return False + elif self.CurrentOffsetWithinLine == 0: + self.CurrentLineNumber -= 1 + self.CurrentOffsetWithinLine = len(self.__CurrentLine()) - 1 + else: + self.CurrentOffsetWithinLine -= 1 + return True + + ## __GetOneChar() method + # + # Move forward one char in the file buffer + # + # @param self The object pointer + # + def __GetOneChar(self): + if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1: + self.CurrentLineNumber += 1 + self.CurrentOffsetWithinLine = 0 + else: + self.CurrentOffsetWithinLine += 1 + + ## __CurrentChar() method + # + # Get the char pointed to by the file buffer pointer + # + # @param self The object pointer + # @retval Char Current char + # + def __CurrentChar(self): + CurrentChar = self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] +# if CurrentChar > 255: +# raise Warning("Non-Ascii char found At Line %d, offset %d" % (self.CurrentLineNumber, self.CurrentOffsetWithinLine), self.FileName, self.CurrentLineNumber) + return CurrentChar + + ## __NextChar() method + # + # Get the one char pass the char pointed to by the file buffer pointer + # + # @param self The object pointer + # @retval Char Next char + # + def __NextChar(self): + if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1: + return self.Profile.FileLinesList[self.CurrentLineNumber][0] + else: + return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine + 1] + + ## __SetCurrentCharValue() method + # + # Modify the value of current char + # + # @param self The object pointer + # @param Value The new value of current char + # + def __SetCurrentCharValue(self, Value): + self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] = Value + + ## __SetCharValue() method + # + # Modify the value of current char + # + # @param self The object pointer + # @param Value The new value of current char + # + def __SetCharValue(self, Line, Offset, Value): + self.Profile.FileLinesList[Line - 1][Offset] = Value + + ## __CurrentLine() method + # + # Get the list that contains current line contents + # + # @param self The object pointer + # @retval List current line contents + # + def __CurrentLine(self): + return self.Profile.FileLinesList[self.CurrentLineNumber - 1] + + ## __InsertComma() method + # + # Insert ',' to replace PP + # + # @param self The object pointer + # @retval List current line contents + # + def __InsertComma(self, Line): + + + if self.Profile.FileLinesList[Line - 1][0] != T_CHAR_HASH: + BeforeHashPart = str(self.Profile.FileLinesList[Line - 1]).split(T_CHAR_HASH)[0] + if BeforeHashPart.rstrip().endswith(T_CHAR_COMMA) or BeforeHashPart.rstrip().endswith(';'): + return + + if Line - 2 >= 0 and str(self.Profile.FileLinesList[Line - 2]).rstrip().endswith(','): + return + + if Line - 2 >= 0 and str(self.Profile.FileLinesList[Line - 2]).rstrip().endswith(';'): + return + + if str(self.Profile.FileLinesList[Line]).lstrip().startswith(',') or str(self.Profile.FileLinesList[Line]).lstrip().startswith(';'): + return + + self.Profile.FileLinesList[Line - 1].insert(self.CurrentOffsetWithinLine, ',') + + ## PreprocessFile() method + # + # Preprocess file contents, replace comments with spaces. + # In the end, rewind the file buffer pointer to the beginning + # BUGBUG: No !include statement processing contained in this procedure + # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1] + # + # @param self The object pointer + # + def PreprocessFile(self): + + self.Rewind() + InComment = False + DoubleSlashComment = False + HashComment = False + PPExtend = False + CommentObj = None + PPDirectiveObj = None + # HashComment in quoted string " " is ignored. + InString = False + InCharLiteral = False + + self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesListFromFile] + while not self.__EndOfFile(): + + if not InComment and self.__CurrentChar() == T_CHAR_DOUBLE_QUOTE: + InString = not InString + + if not InComment and self.__CurrentChar() == T_CHAR_SINGLE_QUOTE: + InCharLiteral = not InCharLiteral + # meet new line, then no longer in a comment for // and '#' + if self.__CurrentChar() == T_CHAR_LF: + if HashComment and PPDirectiveObj != None: + if PPDirectiveObj.Content.rstrip(T_CHAR_CR).endswith(T_CHAR_BACKSLASH): + PPDirectiveObj.Content += T_CHAR_LF + PPExtend = True + else: + PPExtend = False + + EndLinePos = (self.CurrentLineNumber, self.CurrentOffsetWithinLine) + + if InComment and DoubleSlashComment: + InComment = False + DoubleSlashComment = False + CommentObj.Content += T_CHAR_LF + CommentObj.EndPos = EndLinePos + FileProfile.CommentList.append(CommentObj) + CommentObj = None + if InComment and HashComment and not PPExtend: + InComment = False + HashComment = False + PPDirectiveObj.Content += T_CHAR_LF + PPDirectiveObj.EndPos = EndLinePos + FileProfile.PPDirectiveList.append(PPDirectiveObj) + PPDirectiveObj = None + + if InString or InCharLiteral: + CurrentLine = "".join(self.__CurrentLine()) + if CurrentLine.rstrip(T_CHAR_LF).rstrip(T_CHAR_CR).endswith(T_CHAR_BACKSLASH): + SlashIndex = CurrentLine.rindex(T_CHAR_BACKSLASH) + self.__SetCharValue(self.CurrentLineNumber, SlashIndex, T_CHAR_SPACE) + + if InComment and not DoubleSlashComment and not HashComment: + CommentObj.Content += T_CHAR_LF + self.CurrentLineNumber += 1 + self.CurrentOffsetWithinLine = 0 + # check for */ comment end + elif InComment and not DoubleSlashComment and not HashComment and self.__CurrentChar() == T_CHAR_STAR and self.__NextChar() == T_CHAR_SLASH: + CommentObj.Content += self.__CurrentChar() +# self.__SetCurrentCharValue(T_CHAR_SPACE) + self.__GetOneChar() + CommentObj.Content += self.__CurrentChar() +# self.__SetCurrentCharValue(T_CHAR_SPACE) + CommentObj.EndPos = (self.CurrentLineNumber, self.CurrentOffsetWithinLine) + FileProfile.CommentList.append(CommentObj) + CommentObj = None + self.__GetOneChar() + InComment = False + # set comments to spaces + elif InComment: + if HashComment: + # // follows hash PP directive + if self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_SLASH: + InComment = False + HashComment = False + PPDirectiveObj.EndPos = (self.CurrentLineNumber, self.CurrentOffsetWithinLine - 1) + FileProfile.PPDirectiveList.append(PPDirectiveObj) + PPDirectiveObj = None + continue + else: + PPDirectiveObj.Content += self.__CurrentChar() + if PPExtend: + self.__SetCurrentCharValue(T_CHAR_SPACE) + else: + CommentObj.Content += self.__CurrentChar() +# self.__SetCurrentCharValue(T_CHAR_SPACE) + self.__GetOneChar() + # check for // comment + elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_SLASH: + InComment = True + DoubleSlashComment = True + CommentObj = Comment('', (self.CurrentLineNumber, self.CurrentOffsetWithinLine), None, T_COMMENT_TWO_SLASH) + # check for '#' comment + elif self.__CurrentChar() == T_CHAR_HASH and not InString and not InCharLiteral: + InComment = True + HashComment = True + PPDirectiveObj = PP_Directive('', (self.CurrentLineNumber, self.CurrentOffsetWithinLine), None) + # check for /* comment start + elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_STAR: + CommentObj = Comment('', (self.CurrentLineNumber, self.CurrentOffsetWithinLine), None, T_COMMENT_SLASH_STAR) + CommentObj.Content += self.__CurrentChar() +# self.__SetCurrentCharValue( T_CHAR_SPACE) + self.__GetOneChar() + CommentObj.Content += self.__CurrentChar() +# self.__SetCurrentCharValue( T_CHAR_SPACE) + self.__GetOneChar() + InComment = True + else: + self.__GetOneChar() + + EndLinePos = (self.CurrentLineNumber, self.CurrentOffsetWithinLine) + + if InComment and DoubleSlashComment: + CommentObj.EndPos = EndLinePos + FileProfile.CommentList.append(CommentObj) + if InComment and HashComment and not PPExtend: + PPDirectiveObj.EndPos = EndLinePos + FileProfile.PPDirectiveList.append(PPDirectiveObj) + + self.Rewind() + + def PreprocessFileWithClear(self): + + self.Rewind() + InComment = False + DoubleSlashComment = False + HashComment = False + PPExtend = False + CommentObj = None + PPDirectiveObj = None + # HashComment in quoted string " " is ignored. + InString = False + InCharLiteral = False + + self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesListFromFile] + while not self.__EndOfFile(): + + if not InComment and self.__CurrentChar() == T_CHAR_DOUBLE_QUOTE: + InString = not InString + + if not InComment and self.__CurrentChar() == T_CHAR_SINGLE_QUOTE: + InCharLiteral = not InCharLiteral + # meet new line, then no longer in a comment for // and '#' + if self.__CurrentChar() == T_CHAR_LF: + if HashComment and PPDirectiveObj != None: + if PPDirectiveObj.Content.rstrip(T_CHAR_CR).endswith(T_CHAR_BACKSLASH): + PPDirectiveObj.Content += T_CHAR_LF + PPExtend = True + else: + PPExtend = False + + EndLinePos = (self.CurrentLineNumber, self.CurrentOffsetWithinLine) + + if InComment and DoubleSlashComment: + InComment = False + DoubleSlashComment = False + CommentObj.Content += T_CHAR_LF + CommentObj.EndPos = EndLinePos + FileProfile.CommentList.append(CommentObj) + CommentObj = None + if InComment and HashComment and not PPExtend: + InComment = False + HashComment = False + PPDirectiveObj.Content += T_CHAR_LF + PPDirectiveObj.EndPos = EndLinePos + FileProfile.PPDirectiveList.append(PPDirectiveObj) + PPDirectiveObj = None + + if InString or InCharLiteral: + CurrentLine = "".join(self.__CurrentLine()) + if CurrentLine.rstrip(T_CHAR_LF).rstrip(T_CHAR_CR).endswith(T_CHAR_BACKSLASH): + SlashIndex = CurrentLine.rindex(T_CHAR_BACKSLASH) + self.__SetCharValue(self.CurrentLineNumber, SlashIndex, T_CHAR_SPACE) + + if InComment and not DoubleSlashComment and not HashComment: + CommentObj.Content += T_CHAR_LF + self.CurrentLineNumber += 1 + self.CurrentOffsetWithinLine = 0 + # check for */ comment end + elif InComment and not DoubleSlashComment and not HashComment and self.__CurrentChar() == T_CHAR_STAR and self.__NextChar() == T_CHAR_SLASH: + CommentObj.Content += self.__CurrentChar() + self.__SetCurrentCharValue(T_CHAR_SPACE) + self.__GetOneChar() + CommentObj.Content += self.__CurrentChar() + self.__SetCurrentCharValue(T_CHAR_SPACE) + CommentObj.EndPos = (self.CurrentLineNumber, self.CurrentOffsetWithinLine) + FileProfile.CommentList.append(CommentObj) + CommentObj = None + self.__GetOneChar() + InComment = False + # set comments to spaces + elif InComment: + if HashComment: + # // follows hash PP directive + if self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_SLASH: + InComment = False + HashComment = False + PPDirectiveObj.EndPos = (self.CurrentLineNumber, self.CurrentOffsetWithinLine - 1) + FileProfile.PPDirectiveList.append(PPDirectiveObj) + PPDirectiveObj = None + continue + else: + PPDirectiveObj.Content += self.__CurrentChar() +# if PPExtend: +# self.__SetCurrentCharValue(T_CHAR_SPACE) + else: + CommentObj.Content += self.__CurrentChar() + self.__SetCurrentCharValue(T_CHAR_SPACE) + self.__GetOneChar() + # check for // comment + elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_SLASH: + InComment = True + DoubleSlashComment = True + CommentObj = Comment('', (self.CurrentLineNumber, self.CurrentOffsetWithinLine), None, T_COMMENT_TWO_SLASH) + # check for '#' comment + elif self.__CurrentChar() == T_CHAR_HASH and not InString and not InCharLiteral: + InComment = True + HashComment = True + PPDirectiveObj = PP_Directive('', (self.CurrentLineNumber, self.CurrentOffsetWithinLine), None) + # check for /* comment start + elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_STAR: + CommentObj = Comment('', (self.CurrentLineNumber, self.CurrentOffsetWithinLine), None, T_COMMENT_SLASH_STAR) + CommentObj.Content += self.__CurrentChar() + self.__SetCurrentCharValue( T_CHAR_SPACE) + self.__GetOneChar() + CommentObj.Content += self.__CurrentChar() + self.__SetCurrentCharValue( T_CHAR_SPACE) + self.__GetOneChar() + InComment = True + else: + self.__GetOneChar() + + EndLinePos = (self.CurrentLineNumber, self.CurrentOffsetWithinLine) + + if InComment and DoubleSlashComment: + CommentObj.EndPos = EndLinePos + FileProfile.CommentList.append(CommentObj) + if InComment and HashComment and not PPExtend: + PPDirectiveObj.EndPos = EndLinePos + FileProfile.PPDirectiveList.append(PPDirectiveObj) + self.Rewind() + + ## ParseFile() method + # + # Parse the file profile buffer to extract fd, fv ... information + # Exception will be raised if syntax error found + # + # @param self The object pointer + # + def ParseFile(self): + self.PreprocessFile() + # restore from ListOfList to ListOfString + self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList] + FileStringContents = '' + for fileLine in self.Profile.FileLinesList: + FileStringContents += fileLine + cStream = antlr3.StringStream(FileStringContents) + lexer = CLexer(cStream) + tStream = antlr3.CommonTokenStream(lexer) + parser = CParser(tStream) + parser.translation_unit() + + def ParseFileWithClearedPPDirective(self): + self.PreprocessFileWithClear() + # restore from ListOfList to ListOfString + self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList] + FileStringContents = '' + for fileLine in self.Profile.FileLinesList: + FileStringContents += fileLine + cStream = antlr3.StringStream(FileStringContents) + lexer = CLexer(cStream) + tStream = antlr3.CommonTokenStream(lexer) + parser = CParser(tStream) + parser.translation_unit() + + def CleanFileProfileBuffer(self): + FileProfile.CommentList = [] + FileProfile.PPDirectiveList = [] + FileProfile.PredicateExpressionList = [] + FileProfile.FunctionDefinitionList = [] + FileProfile.VariableDeclarationList = [] + FileProfile.EnumerationDefinitionList = [] + FileProfile.StructUnionDefinitionList = [] + FileProfile.TypedefDefinitionList = [] + FileProfile.FunctionCallingList = [] + + def PrintFragments(self): + + print '################# ' + self.FileName + '#####################' + + print '/****************************************/' + print '/*************** COMMENTS ***************/' + print '/****************************************/' + for comment in FileProfile.CommentList: + print str(comment.StartPos) + comment.Content + + print '/****************************************/' + print '/********* PREPROCESS DIRECTIVES ********/' + print '/****************************************/' + for pp in FileProfile.PPDirectiveList: + print str(pp.StartPos) + pp.Content + + print '/****************************************/' + print '/********* VARIABLE DECLARATIONS ********/' + print '/****************************************/' + for var in FileProfile.VariableDeclarationList: + print str(var.StartPos) + var.Modifier + ' '+ var.Declarator + + print '/****************************************/' + print '/********* FUNCTION DEFINITIONS *********/' + print '/****************************************/' + for func in FileProfile.FunctionDefinitionList: + print str(func.StartPos) + func.Modifier + ' '+ func.Declarator + ' ' + str(func.NamePos) + + print '/****************************************/' + print '/************ ENUMERATIONS **************/' + print '/****************************************/' + for enum in FileProfile.EnumerationDefinitionList: + print str(enum.StartPos) + enum.Content + + print '/****************************************/' + print '/*********** STRUCTS/UNIONS *************/' + print '/****************************************/' + for su in FileProfile.StructUnionDefinitionList: + print str(su.StartPos) + su.Content + + print '/****************************************/' + print '/********* PREDICATE EXPRESSIONS ********/' + print '/****************************************/' + for predexp in FileProfile.PredicateExpressionList: + print str(predexp.StartPos) + predexp.Content + + print '/****************************************/' + print '/************** TYPEDEFS ****************/' + print '/****************************************/' + for typedef in FileProfile.TypedefDefinitionList: + print str(typedef.StartPos) + typedef.ToType + +if __name__ == "__main__": + + collector = CodeFragmentCollector(sys.argv[1]) + collector.PreprocessFile() + print "For Test." diff --git a/BaseTools/Source/Python/Ecc/Configuration.py b/BaseTools/Source/Python/Ecc/Configuration.py new file mode 100644 index 0000000000..bd9313cef4 --- /dev/null +++ b/BaseTools/Source/Python/Ecc/Configuration.py @@ -0,0 +1,264 @@ +## @file +# This file is used to define class Configuration +# +# Copyright (c) 2008, 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 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 Common.EdkLogger as EdkLogger +from Common.DataType import * +from Common.String import * + +## Configuration +# +# This class is used to define all items in configuration file +# +# @param Filename: The name of configuration file, the default is config.ini +# +class Configuration(object): + def __init__(self, Filename): + self.Filename = Filename + + self.Version = 0.1 + + ## Identify to if check all items + # 1 - Check all items and ignore all other detailed items + # 0 - Not check all items, the tool will go through all other detailed items to decide to check or not + # + self.CheckAll = 0 + + ## Identify to if automatically correct mistakes + # 1 - Automatically correct + # 0 - Not automatically correct + # Only the following check points can be automatically corrected, others not listed below are not supported even it is 1 + # + # GeneralCheckTab + # GeneralCheckIndentation + # GeneralCheckLine + # GeneralCheckCarriageReturn + # SpaceCheckAll + # + self.AutoCorrect = 0 + + # List customized Modifer here, split with ',' + # Defaultly use the definition in class DataType + self.ModifierList = MODIFIER_LIST + + ## General Checking + self.GeneralCheckAll = 0 + + # Check whether NO Tab is used, replaced with spaces + self.GeneralCheckNoTab = 1 + # The width of Tab + self.GeneralCheckTabWidth = 2 + # Check whether the indentation is followed coding style + self.GeneralCheckIndentation = 1 + # The width of indentation + self.GeneralCheckIndentationWidth = 2 + # Check whether no line is exceeding defined widty + self.GeneralCheckLine = 1 + # The width of a line + self.GeneralCheckLineWidth = 120 + # Check whether no use of _asm in the source file + self.GeneralCheckNo_Asm = 1 + # Check whether no use of "#progma" in source file except "#pragma pack(#)". + self.GeneralCheckNoProgma = 1 + # Check whether there is a carriage return at the end of the file + self.GeneralCheckCarriageReturn = 1 + # Check whether the file exists + self.GeneralCheckFileExistence = 1 + + ## Space Checking + self.SpaceCheckAll = 1 + + ## Predicate Expression Checking + self.PredicateExpressionCheckAll = 0 + + # Check whether Boolean values, variable type BOOLEAN not use explicit comparisons to TRUE or FALSE + self.PredicateExpressionCheckBooleanValue = 1 + # Check whether Non-Boolean comparisons use a compare operator (==, !=, >, < >=, <=). + self.PredicateExpressionCheckNonBooleanOperator = 1 + # Check whether a comparison of any pointer to zero must be done via the NULL type + self.PredicateExpressionCheckComparisonNullType = 1 + + ## Headers Checking + self.HeaderCheckAll = 0 + + # Check whether File header exists + self.HeaderCheckFile = 1 + # Check whether Function header exists + self.HeaderCheckFunction = 1 + + ## C Function Layout Checking + self.CFunctionLayoutCheckAll = 0 + + # Check whether return type exists and in the first line + self.CFunctionLayoutCheckReturnType = 1 + # Check whether any optional functional modifiers exist and next to the return type + self.CFunctionLayoutCheckOptionalFunctionalModifier = 1 + # Check whether the next line contains the function name, left justified, followed by the beginning of the parameter list + # Check whether the closing parenthesis is on its own line and also indented two spaces + self.CFunctionLayoutCheckFunctionName = 1 + # Check whether the function prototypes in include files have the same form as function definitions + self.CFunctionLayoutCheckFunctionPrototype = 1 + # Check whether the body of a function is contained by open and close braces that must be in the first column + self.CFunctionLayoutCheckFunctionBody = 1 + # Check whether the data declarations is the first code in a module. + self.CFunctionLayoutCheckDataDeclaration = 1 + # Check whether no initialization of a variable as part of its declaration + self.CFunctionLayoutCheckNoInitOfVariable = 1 + # Check whether no use of STATIC for functions + self.CFunctionLayoutCheckNoStatic = 1 + + ## Include Files Checking + self.IncludeFileCheckAll = 0 + + #Check whether having include files with same name + self.IncludeFileCheckSameName = 1 + # Check whether all include file contents is guarded by a #ifndef statement. + # the #ifndef must be the first line of code following the file header comment + # the #endif must appear on the last line in the file + self.IncludeFileCheckIfndefStatement = 1 + # Check whether include files contain only public or only private data + # Check whether include files NOT contain code or define data variables + self.IncludeFileCheckData = 1 + + ## Declarations and Data Types Checking + self.DeclarationDataTypeCheckAll = 0 + + # Check whether no use of int, unsigned, char, void, static, long in any .c, .h or .asl files. + self.DeclarationDataTypeCheckNoUseCType = 1 + # Check whether the modifiers IN, OUT, OPTIONAL, and UNALIGNED are used only to qualify arguments to a function and should not appear in a data type declaration + self.DeclarationDataTypeCheckInOutModifier = 1 + # Check whether the EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols + self.DeclarationDataTypeCheckEFIAPIModifier = 1 + # Check whether Enumerated Type has a 'typedef' and the name is capital + self.DeclarationDataTypeCheckEnumeratedType = 1 + # Check whether Structure Type has a 'typedef' and the name is capital + self.DeclarationDataTypeCheckStructureDeclaration = 1 + # Check whether having same Structure + self.DeclarationDataTypeCheckSameStructure = 1 + # Check whether Union Type has a 'typedef' and the name is capital + self.DeclarationDataTypeCheckUnionType = 1 + + ## Naming Conventions Checking + self.NamingConventionCheckAll = 0 + + # Check whether only capital letters are used for #define declarations + self.NamingConventionCheckDefineStatement = 1 + # Check whether only capital letters are used for typedef declarations + self.NamingConventionCheckTypedefStatement = 1 + # Check whether the #ifndef at the start of an include file uses both prefix and postfix underscore characters, '_'. + self.NamingConventionCheckIfndefStatement = 1 + # Rule for path name, variable name and function name + # 1. First character should be upper case + # 2. Existing lower case in a word + # 3. No space existence + # Check whether the path name followed the rule + self.NamingConventionCheckPathName = 1 + # Check whether the variable name followed the rule + self.NamingConventionCheckVariableName = 1 + # Check whether the function name followed the rule + self.NamingConventionCheckFunctionName = 1 + # Check whether NO use short variable name with single character + self.NamingConventionCheckSingleCharacterVariable = 1 + + ## Doxygen Checking + self.DoxygenCheckAll = 0 + + # Check whether the file headers are followed Doxygen special documentation blocks in section 2.3.5 + self.DoxygenCheckFileHeader = 1 + # Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5 + self.DoxygenCheckFunctionHeader = 1 + # Check whether the first line of text in a comment block is a brief description of the element being documented. + # The brief description must end with a period. + self.DoxygenCheckCommentDescription = 1 + # Check whether comment lines with '///< ... text ...' format, if it is used, it should be after the code section. + self.DoxygenCheckCommentFormat = 1 + # Check whether only Doxygen commands allowed to mark the code are @bug and @todo. + self.DoxygenCheckCommand = 1 + + ## Meta-Data File Processing Checking + self.MetaDataFileCheckAll = 0 + + # Check whether each file defined in meta-data exists + self.MetaDataFileCheckPathName = 1 + # Generate a list for all files defined in meta-data files + self.MetaDataFileCheckGenerateFileList = 1 + # The path of log file + self.MetaDataFileCheckPathOfGenerateFileList = 'File.log' + # Check whether all Library Instances defined for a given module (or dependent library instance) match the module's type. + # Each Library Instance must specify the Supported Module Types in its INF file, + # and any module specifying the library instance must be one of the supported types. + self.MetaDataFileCheckLibraryInstance = 1 + # Check whether a Library Instance has been defined for all dependent library classes + self.MetaDataFileCheckLibraryInstanceDependent = 1 + # Check whether the Library Instances specified by the LibraryClasses sections are listed in order of dependencies + self.MetaDataFileCheckLibraryInstanceOrder = 1 + # Check whether the unnecessary inclusion of library classes in the INF file + self.MetaDataFileCheckLibraryNoUse = 1 + # Check whether an INF file is specified in the FDF file, but not in the DSC file, then the INF file must be for a Binary module only + self.MetaDataFileCheckBinaryInfInFdf = 1 + # Not to report error and warning related OS include file such as "windows.h" and "stdio.h" + # Check whether a PCD is set in a DSC file or the FDF file, but not in both. + self.MetaDataFileCheckPcdDuplicate = 1 + # Check whether PCD settings in the FDF file can only be related to flash. + self.MetaDataFileCheckPcdFlash = 1 + # Check whether PCDs used in INF files but not specified in DSC or FDF files + self.MetaDataFileCheckPcdNoUse = 1 + # Check whether having duplicate guids defined for Guid/Protocol/Ppi + self.MetaDataFileCheckGuidDuplicate = 1 + # Check whether all files under module directory are described in INF files + self.MetaDataFileCheckModuleFileNoUse = 1 + # Check whether the PCD is correctly used in C function via its type + self.MetaDataFileCheckPcdType = 1 + + # + # The check points in this section are reserved + # + # GotoStatementCheckAll = 0 + # + self.SpellingCheckAll = 0 + + # The directory listed here will not be parsed, split with ',' + self.SkipDirList = [] + + self.ParseConfig() + + def ParseConfig(self): + Filepath = os.path.normpath(self.Filename) + if not os.path.isfile(Filepath): + ErrorMsg = "Can't find configuration file '%s'" % Filepath + EdkLogger.error("Ecc", EdkLogger.ECC_ERROR, ErrorMsg, File = Filepath) + + LineNo = 0 + for Line in open(Filepath, 'r'): + LineNo = LineNo + 1 + Line = CleanString(Line) + if Line != '': + List = GetSplitValueList(Line, TAB_EQUAL_SPLIT) + if List[0] not in self.__dict__: + ErrorMsg = "Invalid configuration option '%s' was found" % List[0] + EdkLogger.error("Ecc", EdkLogger.ECC_ERROR, ErrorMsg, File = Filepath, Line = LineNo) + if List[0] == 'ModifierList': + List[1] = GetSplitValueList(List[1], TAB_COMMA_SPLIT) + if List[0] == 'MetaDataFileCheckPathOfGenerateFileList' and List[1] == "": + continue + if List[0] == 'SkipDirList': + List[1] = GetSplitValueList(List[1], TAB_COMMA_SPLIT) + self.__dict__[List[0]] = List[1] + + def ShowMe(self): + print self.Filename + for Key in self.__dict__.keys(): + print Key, '=', self.__dict__[Key] diff --git a/BaseTools/Source/Python/Ecc/Database.py b/BaseTools/Source/Python/Ecc/Database.py new file mode 100644 index 0000000000..c9311f65a5 --- /dev/null +++ b/BaseTools/Source/Python/Ecc/Database.py @@ -0,0 +1,344 @@ +## @file +# This file is used to create a database used by ECC tool +# +# Copyright (c) 2007 ~ 2008, 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 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, time + +import Common.EdkLogger as EdkLogger +import CommonDataClass.DataClass as DataClass + +from Table.TableDataModel import TableDataModel +from Table.TableFile import TableFile +from Table.TableFunction import TableFunction +from Table.TablePcd import TablePcd +from Table.TableIdentifier import TableIdentifier +from Table.TableReport import TableReport +from Table.TableInf import TableInf +from Table.TableDec import TableDec +from Table.TableDsc import TableDsc +from Table.TableFdf import TableFdf + +## +# Static definitions +# +DATABASE_PATH = "Ecc.db" + +## Database +# +# This class defined the ECC databse +# During the phase of initialization, the database will create all tables and +# insert all records of table DataModel +# +# @param object: Inherited from object class +# @param DbPath: A string for the path of the ECC database +# +# @var Conn: Connection of the ECC database +# @var Cur: Cursor of the connection +# @var TblDataModel: Local instance for TableDataModel +# +class Database(object): + def __init__(self, DbPath): + self.DbPath = DbPath + self.Conn = None + self.Cur = None + self.TblDataModel = None + self.TblFile = None + self.TblFunction = None + self.TblIdentifier = None + self.TblPcd = None + self.TblReport = None + self.TblInf = None + self.TblDec = None + self.TblDsc = None + self.TblFdf = None + + ## Initialize ECC database + # + # 1. Delete all old existing tables + # 2. Create new tables + # 3. Initialize table DataModel + # + def InitDatabase(self, NewDatabase = True): + EdkLogger.verbose("\nInitialize ECC database started ...") + # + # Drop all old existing tables + # + if NewDatabase: + if os.path.exists(self.DbPath): + os.remove(self.DbPath) + self.Conn = sqlite3.connect(self.DbPath, isolation_level = 'DEFERRED') + self.Conn.execute("PRAGMA page_size=4096") + self.Conn.execute("PRAGMA synchronous=OFF") + # to avoid non-ascii charater conversion error + self.Conn.text_factory = str + self.Cur = self.Conn.cursor() + + self.TblDataModel = TableDataModel(self.Cur) + self.TblFile = TableFile(self.Cur) + self.TblFunction = TableFunction(self.Cur) + self.TblIdentifier = TableIdentifier(self.Cur) + self.TblPcd = TablePcd(self.Cur) + self.TblReport = TableReport(self.Cur) + self.TblInf = TableInf(self.Cur) + self.TblDec = TableDec(self.Cur) + self.TblDsc = TableDsc(self.Cur) + self.TblFdf = TableFdf(self.Cur) + + # + # Create new tables + # + if NewDatabase: + self.TblDataModel.Create() + self.TblFile.Create() + self.TblFunction.Create() + self.TblPcd.Create() + self.TblReport.Create() + self.TblInf.Create() + self.TblDec.Create() + self.TblDsc.Create() + self.TblFdf.Create() + + # + # Init each table's ID + # + self.TblDataModel.InitID() + self.TblFile.InitID() + self.TblFunction.InitID() + self.TblPcd.InitID() + self.TblReport.InitID() + self.TblInf.InitID() + self.TblDec.InitID() + self.TblDsc.InitID() + self.TblFdf.InitID() + + # + # Initialize table DataModel + # + if NewDatabase: + self.TblDataModel.InitTable() + + EdkLogger.verbose("Initialize ECC database ... DONE!") + + ## Query a table + # + # @param Table: The instance of the table to be queried + # + def QueryTable(self, Table): + Table.Query() + + ## Close entire database + # + # Commit all first + # Close the connection and cursor + # + def Close(self): + # + # Commit to file + # + self.Conn.commit() + + # + # Close connection and cursor + # + self.Cur.close() + self.Conn.close() + + ## Insert one file information + # + # Insert one file's information to the database + # 1. Create a record in TableFile + # 2. Create functions one by one + # 2.1 Create variables of function one by one + # 2.2 Create pcds of function one by one + # 3. Create variables one by one + # 4. Create pcds one by one + # + def InsertOneFile(self, File): + # + # Insert a record for file + # + FileID = self.TblFile.Insert(File.Name, File.ExtName, File.Path, File.FullPath, Model = File.Model, TimeStamp = File.TimeStamp) + IdTable = TableIdentifier(self.Cur) + IdTable.Table = "Identifier%s" % FileID + IdTable.Create() + + # + # Insert function of file + # + for Function in File.FunctionList: + FunctionID = self.TblFunction.Insert(Function.Header, Function.Modifier, Function.Name, Function.ReturnStatement, \ + Function.StartLine, Function.StartColumn, Function.EndLine, Function.EndColumn, \ + Function.BodyStartLine, Function.BodyStartColumn, FileID, \ + Function.FunNameStartLine, Function.FunNameStartColumn) + # + # Insert Identifier of function + # + for Identifier in Function.IdentifierList: + IdentifierID = IdTable.Insert(Identifier.Modifier, Identifier.Type, Identifier.Name, Identifier.Value, Identifier.Model, \ + FileID, FunctionID, Identifier.StartLine, Identifier.StartColumn, Identifier.EndLine, Identifier.EndColumn) + # + # Insert Pcd of function + # + for Pcd in Function.PcdList: + PcdID = self.TblPcd.Insert(Pcd.CName, Pcd.TokenSpaceGuidCName, Pcd.Token, Pcd.DatumType, Pcd.Model, \ + FileID, FunctionID, Pcd.StartLine, Pcd.StartColumn, Pcd.EndLine, Pcd.EndColumn) + # + # Insert Identifier of file + # + for Identifier in File.IdentifierList: + IdentifierID = IdTable.Insert(Identifier.Modifier, Identifier.Type, Identifier.Name, Identifier.Value, Identifier.Model, \ + FileID, -1, Identifier.StartLine, Identifier.StartColumn, Identifier.EndLine, Identifier.EndColumn) + # + # Insert Pcd of file + # + for Pcd in File.PcdList: + PcdID = self.TblPcd.Insert(Pcd.CName, Pcd.TokenSpaceGuidCName, Pcd.Token, Pcd.DatumType, Pcd.Model, \ + FileID, -1, Pcd.StartLine, Pcd.StartColumn, Pcd.EndLine, Pcd.EndColumn) + + EdkLogger.verbose("Insert information from file %s ... DONE!" % File.FullPath) + + ## UpdateIdentifierBelongsToFunction + # + # Update the field "BelongsToFunction" for each Indentifier + # + # + def UpdateIdentifierBelongsToFunction_disabled(self): + EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers started ...") + + SqlCommand = """select ID, BelongsToFile, StartLine, EndLine, Model from Identifier""" + EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand) + self.Cur.execute(SqlCommand) + Records = self.Cur.fetchall() + for Record in Records: + IdentifierID = Record[0] + BelongsToFile = Record[1] + StartLine = Record[2] + EndLine = Record[3] + Model = Record[4] + + # + # Check whether an identifier belongs to a function + # + EdkLogger.debug(4, "For common identifiers ... ") + SqlCommand = """select ID from Function + where StartLine < %s and EndLine > %s + and BelongsToFile = %s""" % (StartLine, EndLine, BelongsToFile) + EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand) + self.Cur.execute(SqlCommand) + IDs = self.Cur.fetchall() + for ID in IDs: + SqlCommand = """Update Identifier set BelongsToFunction = %s where ID = %s""" % (ID[0], IdentifierID) + EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand) + self.Cur.execute(SqlCommand) + + # + # Check whether the identifier is a function header + # + EdkLogger.debug(4, "For function headers ... ") + if Model == DataClass.MODEL_IDENTIFIER_COMMENT: + SqlCommand = """select ID from Function + where StartLine = %s + 1 + and BelongsToFile = %s""" % (EndLine, BelongsToFile) + EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand) + self.Cur.execute(SqlCommand) + IDs = self.Cur.fetchall() + for ID in IDs: + SqlCommand = """Update Identifier set BelongsToFunction = %s, Model = %s where ID = %s""" % (ID[0], DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER, IdentifierID) + EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand) + self.Cur.execute(SqlCommand) + + EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers ... DONE") + + + ## UpdateIdentifierBelongsToFunction + # + # Update the field "BelongsToFunction" for each Indentifier + # + # + def UpdateIdentifierBelongsToFunction(self): + EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers started ...") + + SqlCommand = """select ID, BelongsToFile, StartLine, EndLine from Function""" + Records = self.TblFunction.Exec(SqlCommand) + Data1 = [] + Data2 = [] + for Record in Records: + FunctionID = Record[0] + BelongsToFile = Record[1] + StartLine = Record[2] + EndLine = Record[3] + #Data1.append(("'file%s'" % BelongsToFile, FunctionID, BelongsToFile, StartLine, EndLine)) + #Data2.append(("'file%s'" % BelongsToFile, FunctionID, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER, BelongsToFile, DataClass.MODEL_IDENTIFIER_COMMENT, StartLine - 1)) + + SqlCommand = """Update Identifier%s set BelongsToFunction = %s where BelongsToFile = %s and StartLine > %s and EndLine < %s""" % \ + (BelongsToFile, FunctionID, BelongsToFile, StartLine, EndLine) + self.TblIdentifier.Exec(SqlCommand) + + SqlCommand = """Update Identifier%s set BelongsToFunction = %s, Model = %s where BelongsToFile = %s and Model = %s and EndLine = %s""" % \ + (BelongsToFile, FunctionID, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER, BelongsToFile, DataClass.MODEL_IDENTIFIER_COMMENT, StartLine - 1) + self.TblIdentifier.Exec(SqlCommand) +# # +# # Check whether an identifier belongs to a function +# # +# print Data1 +# SqlCommand = """Update ? set BelongsToFunction = ? where BelongsToFile = ? and StartLine > ? and EndLine < ?""" +# print SqlCommand +# EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand) +# self.Cur.executemany(SqlCommand, Data1) +# +# # +# # Check whether the identifier is a function header +# # +# EdkLogger.debug(4, "For function headers ... ") +# SqlCommand = """Update ? set BelongsToFunction = ?, Model = ? where BelongsToFile = ? and Model = ? and EndLine = ?""" +# EdkLogger.debug(4, "SqlCommand: %s" %SqlCommand) +# self.Cur.executemany(SqlCommand, Data2) +# +# EdkLogger.verbose("Update 'BelongsToFunction' for Identifiers ... DONE") + + +## +# +# 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.VERBOSE) + EdkLogger.SetLevel(EdkLogger.DEBUG_0) + EdkLogger.verbose("Start at " + time.strftime('%H:%M:%S', time.localtime())) + + Db = Database(DATABASE_PATH) + Db.InitDatabase() + Db.QueryTable(Db.TblDataModel) + + identifier1 = DataClass.IdentifierClass(-1, '', '', "i''1", 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 32, 43, 54, 43) + identifier2 = DataClass.IdentifierClass(-1, '', '', 'i1', 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 15, 43, 20, 43) + identifier3 = DataClass.IdentifierClass(-1, '', '', 'i1', 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 55, 43, 58, 43) + identifier4 = DataClass.IdentifierClass(-1, '', '', "i1'", 'aaa', DataClass.MODEL_IDENTIFIER_COMMENT, 1, -1, 77, 43, 88, 43) + fun1 = DataClass.FunctionClass(-1, '', '', 'fun1', '', 21, 2, 60, 45, 1, 23, 0, [], []) + file = DataClass.FileClass(-1, 'F1', 'c', 'C:\\', 'C:\\F1.exe', DataClass.MODEL_FILE_C, '2007-12-28', [fun1], [identifier1, identifier2, identifier3, identifier4], []) + Db.InsertOneFile(file) + Db.UpdateIdentifierBelongsToFunction() + + Db.QueryTable(Db.TblFile) + Db.QueryTable(Db.TblFunction) + Db.QueryTable(Db.TblPcd) + Db.QueryTable(Db.TblIdentifier) + + Db.Close() + EdkLogger.verbose("End at " + time.strftime('%H:%M:%S', time.localtime())) + diff --git a/BaseTools/Source/Python/Ecc/Ecc.py b/BaseTools/Source/Python/Ecc/Ecc.py new file mode 100644 index 0000000000..4767645d05 --- /dev/null +++ b/BaseTools/Source/Python/Ecc/Ecc.py @@ -0,0 +1,329 @@ +## @file +# This file is used to be the main entrance of ECC tool +# +# Copyright (c) 2009, 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 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, time, glob, sys +import Common.EdkLogger as EdkLogger +import Database +import EccGlobalData +from MetaDataParser import * +from optparse import OptionParser +from Configuration import Configuration +from Check import Check +from Common.InfClassObject import Inf +from Common.DecClassObject import Dec +from Common.DscClassObject import Dsc +from Common.FdfClassObject import Fdf +from Common.String import NormPath +from Common import BuildToolError +import c +from Exception import * + +## Ecc +# +# This class is used to define Ecc main entrance +# +# @param object: Inherited from object class +# +class Ecc(object): + def __init__(self): + # Version and Copyright + self.VersionNumber = "0.01" + self.Version = "%prog Version " + self.VersionNumber + self.Copyright = "Copyright (c) 2009, Intel Corporation All rights reserved." + + self.InitDefaultConfigIni() + self.OutputFile = 'output.txt' + self.ReportFile = 'Report.csv' + self.ExceptionFile = 'exception.xml' + self.IsInit = True + self.ScanSourceCode = True + self.ScanMetaData = True + + # Parse the options and args + self.ParseOption() + + # Generate checkpoints list + EccGlobalData.gConfig = Configuration(self.ConfigFile) + + # Generate exception list + EccGlobalData.gException = ExceptionCheck(self.ExceptionFile) + + # Init Ecc database + EccGlobalData.gDb = Database.Database(Database.DATABASE_PATH) + EccGlobalData.gDb.InitDatabase(self.IsInit) + + # Build ECC database + self.BuildDatabase() + + # Start to check + self.Check() + + # Show report + self.GenReport() + + # Close Database + EccGlobalData.gDb.Close() + + def InitDefaultConfigIni(self): + paths = map(lambda p: os.path.join(p, 'Ecc', 'config.ini'), sys.path) + paths = (os.path.realpath('config.ini'),) + tuple(paths) + for path in paths: + if os.path.exists(path): + self.ConfigFile = path + return + self.ConfigFile = 'config.ini' + + ## BuildDatabase + # + # Build the database for target + # + def BuildDatabase(self): + # Clean report table + EccGlobalData.gDb.TblReport.Drop() + EccGlobalData.gDb.TblReport.Create() + + # Build database + if self.IsInit: + if self.ScanSourceCode: + EdkLogger.quiet("Building database for source code ...") + c.CollectSourceCodeDataIntoDB(EccGlobalData.gTarget) + if self.ScanMetaData: + EdkLogger.quiet("Building database for source code done!") + self.BuildMetaDataFileDatabase() + + EccGlobalData.gIdentifierTableList = GetTableList((MODEL_FILE_C, MODEL_FILE_H), 'Identifier', EccGlobalData.gDb) + + ## BuildMetaDataFileDatabase + # + # Build the database for meta data files + # + def BuildMetaDataFileDatabase(self): + EdkLogger.quiet("Building database for meta data files ...") + Op = open(EccGlobalData.gConfig.MetaDataFileCheckPathOfGenerateFileList, 'w+') + #SkipDirs = Read from config file + SkipDirs = EccGlobalData.gConfig.SkipDirList + for Root, Dirs, Files in os.walk(EccGlobalData.gTarget): + for Dir in Dirs: + if Dir.upper() in SkipDirs: + Dirs.remove(Dir) + + for Dir in Dirs: + Dirname = os.path.join(Root, Dir) + if os.path.islink(Dirname): + Dirname = os.path.realpath(Dirname) + if os.path.isdir(Dirname): + # symlinks to directories are treated as directories + Dirs.remove(Dir) + Dirs.append(Dirname) + + for File in Files: + if len(File) > 4 and File[-4:].upper() == ".DEC": + Filename = os.path.normpath(os.path.join(Root, File)) + EdkLogger.quiet("Parsing %s" % Filename) + Op.write("%s\r" % Filename) + Dec(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb) + continue + if len(File) > 4 and File[-4:].upper() == ".DSC": + Filename = os.path.normpath(os.path.join(Root, File)) + EdkLogger.quiet("Parsing %s" % Filename) + Op.write("%s\r" % Filename) + Dsc(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb) + continue + if len(File) > 4 and File[-4:].upper() == ".INF": + Filename = os.path.normpath(os.path.join(Root, File)) + EdkLogger.quiet("Parsing %s" % Filename) + Op.write("%s\r" % Filename) + Inf(Filename, True, True, EccGlobalData.gWorkspace, EccGlobalData.gDb) + continue + if len(File) > 4 and File[-4:].upper() == ".FDF": + Filename = os.path.normpath(os.path.join(Root, File)) + EdkLogger.quiet("Parsing %s" % Filename) + Op.write("%s\r" % Filename) + Fdf(Filename, True, EccGlobalData.gWorkspace, EccGlobalData.gDb) + continue + Op.close() + + # Commit to database + EccGlobalData.gDb.Conn.commit() + + EdkLogger.quiet("Building database for meta data files done!") + + ## + # + # Check each checkpoint + # + def Check(self): + EdkLogger.quiet("Checking ...") + EccCheck = Check() + EccCheck.Check() + EdkLogger.quiet("Checking done!") + + ## + # + # Generate the scan report + # + def GenReport(self): + EdkLogger.quiet("Generating report ...") + EccGlobalData.gDb.TblReport.ToCSV(self.ReportFile) + EdkLogger.quiet("Generating report done!") + + def GetRealPathCase(self, path): + TmpPath = path.rstrip(os.sep) + PathParts = TmpPath.split(os.sep) + if len(PathParts) == 0: + return path + if len(PathParts) == 1: + if PathParts[0].strip().endswith(':'): + return PathParts[0].upper() + # Relative dir, list . current dir + Dirs = os.listdir('.') + for Dir in Dirs: + if Dir.upper() == PathParts[0].upper(): + return Dir + + if PathParts[0].strip().endswith(':'): + PathParts[0] = PathParts[0].upper() + ParentDir = PathParts[0] + RealPath = ParentDir + if PathParts[0] == '': + RealPath = os.sep + ParentDir = os.sep + + PathParts.remove(PathParts[0]) # need to remove the parent + for Part in PathParts: + Dirs = os.listdir(ParentDir + os.sep) + for Dir in Dirs: + if Dir.upper() == Part.upper(): + RealPath += os.sep + RealPath += Dir + break + ParentDir += os.sep + ParentDir += Dir + + return RealPath + + ## ParseOption + # + # Parse options + # + def ParseOption(self): + EdkLogger.quiet("Loading ECC configuration ... done") + (Options, Target) = self.EccOptionParser() + + # Check workspace envirnoment + if "WORKSPACE" not in os.environ: + EdkLogger.error("ECC", BuildToolError.ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found", + ExtraData="WORKSPACE") + else: + EccGlobalData.gWorkspace = os.path.normpath(os.getenv("WORKSPACE")) + if not os.path.exists(EccGlobalData.gWorkspace): + EdkLogger.error("ECC", BuildToolError.FILE_NOT_FOUND, ExtraData="WORKSPACE = %s" % EccGlobalData.gWorkspace) + os.environ["WORKSPACE"] = EccGlobalData.gWorkspace + # Set log level + self.SetLogLevel(Options) + + # Set other options + if Options.ConfigFile != None: + self.ConfigFile = Options.ConfigFile + if Options.OutputFile != None: + self.OutputFile = Options.OutputFile + if Options.ReportFile != None: + self.ReportFile = Options.ReportFile + if Options.Target != None: + if not os.path.isdir(Options.Target): + EdkLogger.error("ECC", BuildToolError.OPTION_VALUE_INVALID, ExtraData="Target [%s] does NOT exist" % Options.Target) + else: + EccGlobalData.gTarget = self.GetRealPathCase(os.path.normpath(Options.Target)) + else: + EdkLogger.warn("Ecc", EdkLogger.ECC_ERROR, "The target source tree was not specified, using current WORKSPACE instead!") + EccGlobalData.gTarget = os.path.normpath(os.getenv("WORKSPACE")) + if Options.keepdatabase != None: + self.IsInit = False + if Options.metadata != None and Options.sourcecode != None: + EdkLogger.error("ECC", BuildToolError.OPTION_CONFLICT, ExtraData="-m and -s can't be specified at one time") + if Options.metadata != None: + self.ScanSourceCode = False + if Options.sourcecode != None: + self.ScanMetaData = False + + ## SetLogLevel + # + # Set current log level of the tool based on args + # + # @param Option: The option list including log level setting + # + def SetLogLevel(self, Option): + if Option.verbose != None: + EdkLogger.SetLevel(EdkLogger.VERBOSE) + elif Option.quiet != None: + EdkLogger.SetLevel(EdkLogger.QUIET) + elif Option.debug != None: + EdkLogger.SetLevel(Option.debug + 1) + else: + EdkLogger.SetLevel(EdkLogger.INFO) + + ## 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 EccOptionParser(self): + Parser = OptionParser(description = self.Copyright, version = self.Version, prog = "Ecc.exe", usage = "%prog [options]") + Parser.add_option("-t", "--target sourcepath", action="store", type="string", dest='Target', + help="Check all files under the target workspace.") + Parser.add_option("-c", "--config filename", action="store", type="string", dest="ConfigFile", + help="Specify a configuration file. Defaultly use config.ini under ECC tool directory.") + Parser.add_option("-o", "--outfile filename", action="store", type="string", dest="OutputFile", + help="Specify the name of an output file, if and only if one filename was specified.") + Parser.add_option("-r", "--reportfile filename", action="store", type="string", dest="ReportFile", + help="Specify the name of an report file, if and only if one filename was specified.") + Parser.add_option("-m", "--metadata", action="store_true", type=None, help="Only scan meta-data files information if this option is specified.") + Parser.add_option("-s", "--sourcecode", action="store_true", type=None, help="Only scan source code files information if this option is specified.") + Parser.add_option("-k", "--keepdatabase", action="store_true", type=None, help="The existing Ecc database will not be cleaned except report information if this option is specified.") + Parser.add_option("-l", "--log filename", action="store", dest="LogFile", help="""If specified, the tool should emit the changes that + were made by the tool after printing the result message. + If filename, the emit to the file, otherwise emit to + standard output. If no modifications were made, then do not + create a log file, or output a log message.""") + Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.") + Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed, "\ + "including library instances selected, final dependency expression, "\ + "and warning messages, etc.") + Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.") + + (Opt, Args)=Parser.parse_args() + + return (Opt, Args) + +## +# +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +# +if __name__ == '__main__': + # Initialize log system + EdkLogger.Initialize() + EdkLogger.IsRaiseError = False + EdkLogger.quiet(time.strftime("%H:%M:%S, %b.%d %Y ", time.localtime()) + "[00:00]" + "\n") + + StartTime = time.clock() + Ecc = Ecc() + FinishTime = time.clock() + + BuildDuration = time.strftime("%M:%S", time.gmtime(int(round(FinishTime - StartTime)))) + EdkLogger.quiet("\n%s [%s]" % (time.strftime("%H:%M:%S, %b.%d %Y", time.localtime()), BuildDuration)) diff --git a/BaseTools/Source/Python/Ecc/EccGlobalData.py b/BaseTools/Source/Python/Ecc/EccGlobalData.py new file mode 100644 index 0000000000..8e8f24b8c8 --- /dev/null +++ b/BaseTools/Source/Python/Ecc/EccGlobalData.py @@ -0,0 +1,24 @@ +## @file +# This file is used to save global datas used by ECC tool +# +# Copyright (c) 2008, 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 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 + +gWorkspace = '' +gTarget = '' +gConfig = None +gDb = None +gIdentifierTableList = [] +gException = None \ No newline at end of file diff --git a/BaseTools/Source/Python/Ecc/EccToolError.py b/BaseTools/Source/Python/Ecc/EccToolError.py new file mode 100644 index 0000000000..9c4d10d55b --- /dev/null +++ b/BaseTools/Source/Python/Ecc/EccToolError.py @@ -0,0 +1,179 @@ +## @file +# Standardized Error Hanlding infrastructures. +# +# Copyright (c) 20087, 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 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. +# + +ERROR_GENERAL_CHECK_ALL = 1000 +ERROR_GENERAL_CHECK_NO_TAB = 1001 +ERROR_GENERAL_CHECK_INDENTATION = 1002 +ERROR_GENERAL_CHECK_LINE = 1003 +ERROR_GENERAL_CHECK_NO_ASM = 1004 +ERROR_GENERAL_CHECK_NO_PROGMA = 1005 +ERROR_GENERAL_CHECK_CARRIAGE_RETURN = 1006 +ERROR_GENERAL_CHECK_FILE_EXISTENCE = 1007 + +ERROR_SPACE_CHECK_ALL = 2000 + +ERROR_PREDICATE_EXPRESSION_CHECK_ALL = 3000 +ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE = 3001 +ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR = 3002 +ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE = 3003 + +ERROR_HEADER_CHECK_ALL = 4000 +ERROR_HEADER_CHECK_FILE = 4001 +ERROR_HEADER_CHECK_FUNCTION = 4002 + +ERROR_C_FUNCTION_LAYOUT_CHECK_ALL = 5000 +ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE = 5001 +ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER = 5002 +ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME = 5003 +ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE = 5004 +ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY = 5005 +ERROR_C_FUNCTION_LAYOUT_CHECK_DATA_DECLARATION = 5006 +ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE = 5007 +ERROR_C_FUNCTION_LAYOUT_CHECK_NO_STATIC = 5008 + +ERROR_INCLUDE_FILE_CHECK_ALL = 6000 +ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_1 = 6001 +ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_2 = 6002 +ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_3 = 6003 +ERROR_INCLUDE_FILE_CHECK_DATA = 6004 +ERROR_INCLUDE_FILE_CHECK_NAME = 6005 + +ERROR_DECLARATION_DATA_TYPE_CHECK_ALL = 7000 +ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE = 7001 +ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER = 7002 +ERROR_DECLARATION_DATA_TYPE_CHECK_EFI_API_MODIFIER = 7003 +ERROR_DECLARATION_DATA_TYPE_CHECK_ENUMERATED_TYPE = 7004 +ERROR_DECLARATION_DATA_TYPE_CHECK_STRUCTURE_DECLARATION = 7005 +ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE = 7007 +ERROR_DECLARATION_DATA_TYPE_CHECK_UNION_TYPE = 7006 +ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE = 7008 + +ERROR_NAMING_CONVENTION_CHECK_ALL = 8000 +ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT = 8001 +ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT = 8002 +ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT = 8003 +ERROR_NAMING_CONVENTION_CHECK_PATH_NAME = 8004 +ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME = 8005 +ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME = 8006 +ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE = 8007 + +ERROR_DOXYGEN_CHECK_ALL = 9000 +ERROR_DOXYGEN_CHECK_FILE_HEADER = 9001 +ERROR_DOXYGEN_CHECK_FUNCTION_HEADER = 9002 +ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION = 9003 +ERROR_DOXYGEN_CHECK_COMMENT_FORMAT = 9004 +ERROR_DOXYGEN_CHECK_COMMAND = 9005 + +ERROR_META_DATA_FILE_CHECK_ALL = 10000 +ERROR_META_DATA_FILE_CHECK_PATH_NAME = 10001 +ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1 = 10002 +ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_2 = 10003 +ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT = 10004 +ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_ORDER = 10005 +ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE = 10006 +ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF = 10007 +ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE = 10008 +ERROR_META_DATA_FILE_CHECK_PCD_FLASH = 10009 +ERROR_META_DATA_FILE_CHECK_PCD_NO_USE = 10010 +ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID = 10011 +ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL = 10012 +ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI = 10013 +ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE = 10014 +ERROR_META_DATA_FILE_CHECK_PCD_TYPE = 10015 + +ERROR_SPELLING_CHECK_ALL = 11000 + +gEccErrorMessage = { + ERROR_GENERAL_CHECK_ALL : "", + ERROR_GENERAL_CHECK_NO_TAB : "'TAB' character is not allowed in source code, please replace each 'TAB' with two spaces", + ERROR_GENERAL_CHECK_INDENTATION : "Indentation does not follow coding style", + ERROR_GENERAL_CHECK_LINE : "The width of each line does not follow coding style", + ERROR_GENERAL_CHECK_NO_ASM : "There should be no use of _asm in the source file", + ERROR_GENERAL_CHECK_NO_PROGMA : """There should be no use of "#progma" in source file except "#pragma pack(#)\"""", + ERROR_GENERAL_CHECK_CARRIAGE_RETURN : "There should be a carriage return at the end of the file", + ERROR_GENERAL_CHECK_FILE_EXISTENCE : "File not found", + + ERROR_SPACE_CHECK_ALL : "", + + ERROR_PREDICATE_EXPRESSION_CHECK_ALL : "", + ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE : "Boolean values and variable type BOOLEAN should not use explicit comparisons to TRUE or FALSE", + ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR : "Non-Boolean comparisons should use a compare operator (==, !=, >, < >=, <=)", + ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE : "A comparison of any pointer to zero must be done via the NULL type", + + ERROR_HEADER_CHECK_ALL : "", + ERROR_HEADER_CHECK_FILE : "File header doesn't exist", + ERROR_HEADER_CHECK_FUNCTION : "Function header doesn't exist", + + ERROR_C_FUNCTION_LAYOUT_CHECK_ALL : "", + ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE : "Return type of a function should exist and in the first line", + ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER : "Any optional functional modifiers should exist and next to the return type", + ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME : """Function name should be left justified, followed by the beginning of the parameter list, with the closing parenthesis on its own line, indented two spaces""", + ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE : "Function prototypes in include files have the same form as function definitions", + ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY : "The body of a function should be contained by open and close braces that must be in the first column", + ERROR_C_FUNCTION_LAYOUT_CHECK_DATA_DECLARATION : "The data declarations should be the first code in a module", + ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE : "There should be no initialization of a variable as part of its declaration", + ERROR_C_FUNCTION_LAYOUT_CHECK_NO_STATIC : "There should be no use of STATIC for functions", + + ERROR_INCLUDE_FILE_CHECK_ALL : "", + ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_1 : "All include file contents should be guarded by a #ifndef statement.", + ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_2 : "The #ifndef must be the first line of code following the file header comment", + ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_3 : "The #endif must appear on the last line in the file", + ERROR_INCLUDE_FILE_CHECK_DATA : "Include files should contain only public or only private data and cannot contain code or define data variables", + ERROR_INCLUDE_FILE_CHECK_NAME : "No permission for the inlcude file with same names", + + ERROR_DECLARATION_DATA_TYPE_CHECK_ALL : "", + ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE : "There should be no use of int, unsigned, char, void, static, long in any .c, .h or .asl files", + ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER : """The modifiers IN, OUT, OPTIONAL, and UNALIGNED should be used only to qualify arguments to a function and should not appear in a data type declaration""", + ERROR_DECLARATION_DATA_TYPE_CHECK_EFI_API_MODIFIER : "The EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols", + ERROR_DECLARATION_DATA_TYPE_CHECK_ENUMERATED_TYPE : "Enumerated Type should have a 'typedef' and the name must be in capital letters", + ERROR_DECLARATION_DATA_TYPE_CHECK_STRUCTURE_DECLARATION : "Structure Type should have a 'typedef' and the name must be in capital letters", + ERROR_DECLARATION_DATA_TYPE_CHECK_SAME_STRUCTURE : "No permission for the structure with same names", + ERROR_DECLARATION_DATA_TYPE_CHECK_UNION_TYPE : "Union Type should have a 'typedef' and the name must be in capital letters", + ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE : "Complex types should be typedef-ed", + + ERROR_NAMING_CONVENTION_CHECK_ALL : "", + ERROR_NAMING_CONVENTION_CHECK_DEFINE_STATEMENT : "Only capital letters are allowed to be used for #define declarations", + ERROR_NAMING_CONVENTION_CHECK_TYPEDEF_STATEMENT : "Only capital letters are allowed to be used for typedef declarations", + ERROR_NAMING_CONVENTION_CHECK_IFNDEF_STATEMENT : "The #ifndef at the start of an include file should use both prefix and postfix underscore characters, '_'", + ERROR_NAMING_CONVENTION_CHECK_PATH_NAME : """Path name does not follow the rules: 1. First character should be upper case 2. Must contain lower case characters 3. No white space characters""", + ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME : """Variable name does not follow the rules: 1. First character should be upper case 2. Must contain lower case characters 3. No white space characters 4. Global variable name must start with a 'g'""", + ERROR_NAMING_CONVENTION_CHECK_FUNCTION_NAME : """Function name does not follow the rules: 1. First character should be upper case 2. Must contain lower case characters 3. No white space characters""", + ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE : "There should be no use of short (single character) variable names", + + ERROR_DOXYGEN_CHECK_ALL : "", + ERROR_DOXYGEN_CHECK_FILE_HEADER : "The file headers should follow Doxygen special documentation blocks in section 2.3.5", + ERROR_DOXYGEN_CHECK_FUNCTION_HEADER : "The function headers should follow Doxygen special documentation blocks in section 2.3.5", + ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION : """The first line of text in a comment block should be a brief description of the element being documented and the brief description must end with a period.""", + ERROR_DOXYGEN_CHECK_COMMENT_FORMAT : "For comment line with '///< ... text ...' format, if it is used, it should be after the code section", + ERROR_DOXYGEN_CHECK_COMMAND : "Only Doxygen commands @bug and @todo are allowed to mark the code", + + ERROR_META_DATA_FILE_CHECK_ALL : "", + ERROR_META_DATA_FILE_CHECK_PATH_NAME : "The file defined in meta-data does not exist", + ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1 : "A library instances defined for a given module (or dependent library instance) doesn't match the module's type.", + ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_2 : "A library instance must specify the Supported Module Types in its INF file", + ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_DEPENDENT : "A library instance must be defined for all dependent library classes", + ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_ORDER : "The library Instances specified by the LibraryClasses sections should be listed in order of dependencies", + ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE : "There should be no unnecessary inclusion of library classes in the INF file", + ERROR_META_DATA_FILE_CHECK_BINARY_INF_IN_FDF : "An INF file is specified in the FDF file, but not in the DSC file, therefore the INF file must be for a Binary module only", + ERROR_META_DATA_FILE_CHECK_PCD_DUPLICATE : "Duplicate PCDs found", + ERROR_META_DATA_FILE_CHECK_PCD_FLASH : "PCD settings in the FDF file should only be related to flash", + ERROR_META_DATA_FILE_CHECK_PCD_NO_USE : "There should be no PCDs declared in INF files that are not specified in in either a DSC or FDF file", + ERROR_META_DATA_FILE_CHECK_DUPLICATE_GUID : "Duplicate GUID found", + ERROR_META_DATA_FILE_CHECK_DUPLICATE_PROTOCOL : "Duplicate PROTOCOL found", + ERROR_META_DATA_FILE_CHECK_DUPLICATE_PPI : "Duplicate PPI found", + ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE : "No used module files found", + ERROR_META_DATA_FILE_CHECK_PCD_TYPE : "Wrong C code function used for this kind of PCD", + + ERROR_SPELLING_CHECK_ALL : "", + } + diff --git a/BaseTools/Source/Python/Ecc/Exception.py b/BaseTools/Source/Python/Ecc/Exception.py new file mode 100644 index 0000000000..733408551a --- /dev/null +++ b/BaseTools/Source/Python/Ecc/Exception.py @@ -0,0 +1,87 @@ +## @file +# This file is used to parse exception items found by ECC tool +# +# Copyright (c) 2009, 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 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 +# +from Common.XmlRoutines import * +import os.path + +# ExceptionXml to parse Exception Node of XML file +class ExceptionXml(object): + def __init__(self): + self.KeyWord = '' + self.ErrorID = '' + self.FilePath = '' + + def FromXml(self, Item, Key): + self.KeyWord = XmlElement(Item, '%s/KeyWord' % Key) + self.ErrorID = XmlElement(Item, '%s/ErrorID' % Key) + self.FilePath = os.path.normpath(XmlElement(Item, '%s/FilePath' % Key)) + + def __str__(self): + return 'ErrorID = %s KeyWord = %s FilePath = %s' %(self.ErrorID, self.KeyWord, self.FilePath) + +# ExceptionListXml to parse Exception Node List of XML file +class ExceptionListXml(object): + def __init__(self): + self.List = [] + + def FromXmlFile(self, FilePath): + XmlContent = XmlParseFile(FilePath) + for Item in XmlList(XmlContent, '/ExceptionList/Exception'): + Exp = ExceptionXml() + Exp.FromXml(Item, 'Exception') + self.List.append(Exp) + + def ToList(self): + RtnList = [] + for Item in self.List: + #RtnList.append((Item.ErrorID, Item.KeyWord, Item.FilePath)) + RtnList.append((Item.ErrorID, Item.KeyWord)) + + return RtnList + + def __str__(self): + RtnStr = '' + if self.List: + for Item in self.List: + RtnStr = RtnStr + str(Item) + '\n' + return RtnStr + +# A class to check exception +class ExceptionCheck(object): + def __init__(self, FilePath = None): + self.ExceptionList = [] + self.ExceptionListXml = ExceptionListXml() + self.LoadExceptionListXml(FilePath) + + def LoadExceptionListXml(self, FilePath): + if FilePath and os.path.isfile(FilePath): + self.ExceptionListXml.FromXmlFile(FilePath) + self.ExceptionList = self.ExceptionListXml.ToList() + + def IsException(self, ErrorID, KeyWord, FileID=-1): + if (str(ErrorID), KeyWord) in self.ExceptionList: + return True + else: + return False + +## +# +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +# +if __name__ == '__main__': + El = ExceptionCheck('C:\\Hess\\Project\\BuildTool\\src\\Ecc\\exception.xml') + print El.ExceptionList diff --git a/BaseTools/Source/Python/Ecc/FileProfile.py b/BaseTools/Source/Python/Ecc/FileProfile.py new file mode 100644 index 0000000000..810087ea07 --- /dev/null +++ b/BaseTools/Source/Python/Ecc/FileProfile.py @@ -0,0 +1,57 @@ +## @file +# fragments of source file +# +# Copyright (c) 2007, 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 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 re +import os +from ParserWarning import Warning + +CommentList = [] +PPDirectiveList = [] +PredicateExpressionList = [] +FunctionDefinitionList = [] +VariableDeclarationList = [] +EnumerationDefinitionList = [] +StructUnionDefinitionList = [] +TypedefDefinitionList = [] +FunctionCallingList = [] + +## record file data when parsing source +# +# May raise Exception when opening file. +# +class FileProfile : + + ## The constructor + # + # @param self The object pointer + # @param FileName The file that to be parsed + # + def __init__(self, FileName): + self.FileLinesList = [] + self.FileLinesListFromFile = [] + try: + fsock = open(FileName, "rb", 0) + try: + self.FileLinesListFromFile = fsock.readlines() + finally: + fsock.close() + + except IOError: + raise Warning("Error when opening file %s" % FileName) + + \ No newline at end of file diff --git a/BaseTools/Source/Python/Ecc/MetaDataParser.py b/BaseTools/Source/Python/Ecc/MetaDataParser.py new file mode 100644 index 0000000000..fb4239f474 --- /dev/null +++ b/BaseTools/Source/Python/Ecc/MetaDataParser.py @@ -0,0 +1,65 @@ +## @file +# This file is used to define common parser functions for meta-data +# +# Copyright (c) 2008, 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 accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# + +import os +from CommonDataClass.DataClass import * + + +## Get the inlcude path list for a source file +# +# 1. Find the source file belongs to which inf file +# 2. Find the inf's package +# 3. Return the include path list of the package +# +def GetIncludeListOfFile(WorkSpace, Filepath, Db): + IncludeList = [] + Filepath = os.path.normpath(Filepath) + SqlCommand = """ + select Value1, FullPath from Inf, File where Inf.Model = %s and Inf.BelongsToFile in( + select distinct B.BelongsToFile from File as A left join Inf as B + where A.ID = B.BelongsToFile and B.Model = %s and (A.Path || '%s' || B.Value1) = '%s') + and Inf.BelongsToFile = File.ID""" \ + % (MODEL_META_DATA_PACKAGE, MODEL_EFI_SOURCE_FILE, '\\', Filepath) + RecordSet = Db.TblFile.Exec(SqlCommand) + for Record in RecordSet: + DecFullPath = os.path.normpath(os.path.join(WorkSpace, Record[0])) + InfFullPath = os.path.normpath(os.path.join(WorkSpace, Record[1])) + (DecPath, DecName) = os.path.split(DecFullPath) + (InfPath, InfName) = os.path.split(InfFullPath) + SqlCommand = """select Value1 from Dec where BelongsToFile = + (select ID from File where FullPath = '%s') and Model = %s""" \ + % (DecFullPath, MODEL_EFI_INCLUDE) + NewRecordSet = Db.TblDec.Exec(SqlCommand) + if InfPath not in IncludeList: + IncludeList.append(InfPath) + for NewRecord in NewRecordSet: + IncludePath = os.path.normpath(os.path.join(DecPath, NewRecord[0])) + if IncludePath not in IncludeList: + IncludeList.append(IncludePath) + + return IncludeList + +## Get the table list +# +# Search table file and find all small tables +# +def GetTableList(FileModelList, Table, Db): + TableList = [] + SqlCommand = """select ID from File where Model in %s""" % str(FileModelList) + RecordSet = Db.TblFile.Exec(SqlCommand) + for Record in RecordSet: + TableName = Table + str(Record[0]) + TableList.append(TableName) + + return TableList + diff --git a/BaseTools/Source/Python/Ecc/ParserWarning.py b/BaseTools/Source/Python/Ecc/ParserWarning.py new file mode 100644 index 0000000000..547360d927 --- /dev/null +++ b/BaseTools/Source/Python/Ecc/ParserWarning.py @@ -0,0 +1,17 @@ +## The exception class that used to report error messages when preprocessing +# +# Currently the "ToolName" is set to be "ECC PP". +# +class Warning (Exception): + ## The constructor + # + # @param self The object pointer + # @param Str The message to record + # @param File The FDF name + # @param Line The Line number that error occurs + # + def __init__(self, Str, File = None, Line = None): + self.message = Str + self.FileName = File + self.LineNumber = Line + self.ToolName = 'ECC PP' \ No newline at end of file diff --git a/BaseTools/Source/Python/Ecc/__init__.py b/BaseTools/Source/Python/Ecc/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/BaseTools/Source/Python/Ecc/c.py b/BaseTools/Source/Python/Ecc/c.py new file mode 100644 index 0000000000..b8b1d2d6f5 --- /dev/null +++ b/BaseTools/Source/Python/Ecc/c.py @@ -0,0 +1,2503 @@ +import sys +import os +import re +import string +import CodeFragmentCollector +import FileProfile +from CommonDataClass import DataClass +import Database +from Common import EdkLogger +from EccToolError import * +import EccGlobalData +import MetaDataParser + +IncludeFileListDict = {} +AllIncludeFileListDict = {} +IncludePathListDict = {} +ComplexTypeDict = {} +SUDict = {} +IgnoredKeywordList = ['EFI_ERROR'] + +def GetIgnoredDirListPattern(): + skipList = list(EccGlobalData.gConfig.SkipDirList) + ['.svn'] + DirString = string.join(skipList, '|') + p = re.compile(r'.*[\\/](?:%s)[\\/]?.*' % DirString) + return p + +def GetFuncDeclPattern(): + p = re.compile(r'(?:EFIAPI|EFI_BOOT_SERVICE|EFI_RUNTIME_SERVICE)?\s*[_\w]+\s*\(.*\)$', re.DOTALL) + return p + +def GetArrayPattern(): + p = re.compile(r'[_\w]*\s*[\[.*\]]+') + return p + +def GetTypedefFuncPointerPattern(): + p = re.compile('[_\w\s]*\([\w\s]*\*+\s*[_\w]+\s*\)\s*\(.*\)', re.DOTALL) + return p + +def GetDB(): + return EccGlobalData.gDb + +def GetConfig(): + return EccGlobalData.gConfig + +def PrintErrorMsg(ErrorType, Msg, TableName, ItemId): + Msg = Msg.replace('\n', '').replace('\r', '') + MsgPartList = Msg.split() + Msg = '' + for Part in MsgPartList: + Msg += Part + Msg += ' ' + GetDB().TblReport.Insert(ErrorType, OtherMsg = Msg, BelongsToTable = TableName, BelongsToItem = ItemId) + +def GetIdType(Str): + Type = DataClass.MODEL_UNKNOWN + Str = Str.replace('#', '# ') + List = Str.split() + if List[1] == 'include': + Type = DataClass.MODEL_IDENTIFIER_INCLUDE + elif List[1] == 'define': + Type = DataClass.MODEL_IDENTIFIER_MACRO_DEFINE + elif List[1] == 'ifdef': + Type = DataClass.MODEL_IDENTIFIER_MACRO_IFDEF + elif List[1] == 'ifndef': + Type = DataClass.MODEL_IDENTIFIER_MACRO_IFNDEF + elif List[1] == 'endif': + Type = DataClass.MODEL_IDENTIFIER_MACRO_ENDIF + elif List[1] == 'pragma': + Type = DataClass.MODEL_IDENTIFIER_MACRO_PROGMA + else: + Type = DataClass.MODEL_UNKNOWN + return Type + +def SuOccurInTypedef (Su, TdList): + for Td in TdList: + if Su.StartPos[0] == Td.StartPos[0] and Su.EndPos[0] == Td.EndPos[0]: + return True + return False + +def GetIdentifierList(): + IdList = [] + for comment in FileProfile.CommentList: + IdComment = DataClass.IdentifierClass(-1, '', '', '', comment.Content, DataClass.MODEL_IDENTIFIER_COMMENT, -1, -1, comment.StartPos[0],comment.StartPos[1],comment.EndPos[0],comment.EndPos[1]) + IdList.append(IdComment) + + for pp in FileProfile.PPDirectiveList: + Type = GetIdType(pp.Content) + IdPP = DataClass.IdentifierClass(-1, '', '', '', pp.Content, Type, -1, -1, pp.StartPos[0],pp.StartPos[1],pp.EndPos[0],pp.EndPos[1]) + IdList.append(IdPP) + + for pe in FileProfile.PredicateExpressionList: + IdPE = DataClass.IdentifierClass(-1, '', '', '', pe.Content, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION, -1, -1, pe.StartPos[0],pe.StartPos[1],pe.EndPos[0],pe.EndPos[1]) + IdList.append(IdPE) + + FuncDeclPattern = GetFuncDeclPattern() + ArrayPattern = GetArrayPattern() + for var in FileProfile.VariableDeclarationList: + DeclText = var.Declarator.lstrip() + FuncPointerPattern = GetTypedefFuncPointerPattern() + if FuncPointerPattern.match(DeclText): + continue + VarNameStartLine = var.NameStartPos[0] + VarNameStartColumn = var.NameStartPos[1] + FirstChar = DeclText[0] + while not FirstChar.isalpha() and FirstChar != '_': + if FirstChar == '*': + var.Modifier += '*' + VarNameStartColumn += 1 + DeclText = DeclText.lstrip('*') + elif FirstChar == '\r': + DeclText = DeclText.lstrip('\r\n').lstrip('\r') + VarNameStartLine += 1 + VarNameStartColumn = 0 + elif FirstChar == '\n': + DeclText = DeclText.lstrip('\n') + VarNameStartLine += 1 + VarNameStartColumn = 0 + elif FirstChar == ' ': + DeclText = DeclText.lstrip(' ') + VarNameStartColumn += 1 + elif FirstChar == '\t': + DeclText = DeclText.lstrip('\t') + VarNameStartColumn += 8 + else: + DeclText = DeclText[1:] + VarNameStartColumn += 1 + FirstChar = DeclText[0] + + var.Declarator = DeclText + if FuncDeclPattern.match(var.Declarator): + DeclSplitList = var.Declarator.split('(') + FuncName = DeclSplitList[0].strip() + FuncNamePartList = FuncName.split() + if len(FuncNamePartList) > 1: + FuncName = FuncNamePartList[-1].strip() + NameStart = DeclSplitList[0].rfind(FuncName) + var.Declarator = var.Declarator[NameStart:] + if NameStart > 0: + var.Modifier += ' ' + DeclSplitList[0][0:NameStart] + Index = 0 + PreChar = '' + while Index < NameStart: + FirstChar = DeclSplitList[0][Index] + if DeclSplitList[0][Index:].startswith('EFIAPI'): + Index += 6 + VarNameStartColumn += 6 + PreChar = '' + continue + elif FirstChar == '\r': + Index += 1 + VarNameStartLine += 1 + VarNameStartColumn = 0 + elif FirstChar == '\n': + Index += 1 + if PreChar != '\r': + VarNameStartLine += 1 + VarNameStartColumn = 0 + elif FirstChar == ' ': + Index += 1 + VarNameStartColumn += 1 + elif FirstChar == '\t': + Index += 1 + VarNameStartColumn += 8 + else: + Index += 1 + VarNameStartColumn += 1 + PreChar = FirstChar + IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', var.Declarator, FuncName, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION, -1, -1, var.StartPos[0], var.StartPos[1], VarNameStartLine, VarNameStartColumn) + IdList.append(IdVar) + continue + + if var.Declarator.find('{') == -1: + for decl in var.Declarator.split(','): + DeclList = decl.split('=') + Name = DeclList[0].strip() + if ArrayPattern.match(Name): + LSBPos = var.Declarator.find('[') + var.Modifier += ' ' + Name[LSBPos:] + Name = Name[0:LSBPos] + + IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', Name, (len(DeclList) > 1 and [DeclList[1]]or [''])[0], DataClass.MODEL_IDENTIFIER_VARIABLE, -1, -1, var.StartPos[0],var.StartPos[1], VarNameStartLine, VarNameStartColumn) + IdList.append(IdVar) + else: + DeclList = var.Declarator.split('=') + Name = DeclList[0].strip() + if ArrayPattern.match(Name): + LSBPos = var.Declarator.find('[') + var.Modifier += ' ' + Name[LSBPos:] + Name = Name[0:LSBPos] + IdVar = DataClass.IdentifierClass(-1, var.Modifier, '', Name, (len(DeclList) > 1 and [DeclList[1]]or [''])[0], DataClass.MODEL_IDENTIFIER_VARIABLE, -1, -1, var.StartPos[0],var.StartPos[1], VarNameStartLine, VarNameStartColumn) + IdList.append(IdVar) + + for enum in FileProfile.EnumerationDefinitionList: + LBPos = enum.Content.find('{') + RBPos = enum.Content.find('}') + Name = enum.Content[4:LBPos].strip() + Value = enum.Content[LBPos+1:RBPos] + IdEnum = DataClass.IdentifierClass(-1, '', '', Name, Value, DataClass.MODEL_IDENTIFIER_ENUMERATE, -1, -1, enum.StartPos[0],enum.StartPos[1],enum.EndPos[0],enum.EndPos[1]) + IdList.append(IdEnum) + + for su in FileProfile.StructUnionDefinitionList: + if SuOccurInTypedef(su, FileProfile.TypedefDefinitionList): + continue + Type = DataClass.MODEL_IDENTIFIER_STRUCTURE + SkipLen = 6 + if su.Content.startswith('union'): + Type = DataClass.MODEL_IDENTIFIER_UNION + SkipLen = 5 + LBPos = su.Content.find('{') + RBPos = su.Content.find('}') + if LBPos == -1 or RBPos == -1: + Name = su.Content[SkipLen:].strip() + Value = '' + else: + Name = su.Content[SkipLen:LBPos].strip() + Value = su.Content[LBPos:RBPos+1] + IdPE = DataClass.IdentifierClass(-1, '', '', Name, Value, Type, -1, -1, su.StartPos[0],su.StartPos[1],su.EndPos[0],su.EndPos[1]) + IdList.append(IdPE) + + TdFuncPointerPattern = GetTypedefFuncPointerPattern() + for td in FileProfile.TypedefDefinitionList: + Modifier = '' + Name = td.ToType + Value = td.FromType + if TdFuncPointerPattern.match(td.ToType): + Modifier = td.FromType + LBPos = td.ToType.find('(') + TmpStr = td.ToType[LBPos+1:].strip() + StarPos = TmpStr.find('*') + if StarPos != -1: + Modifier += ' ' + TmpStr[0:StarPos] + while TmpStr[StarPos] == '*': +# Modifier += ' ' + '*' + StarPos += 1 + TmpStr = TmpStr[StarPos:].strip() + RBPos = TmpStr.find(')') + Name = TmpStr[0:RBPos] + Value = 'FP' + TmpStr[RBPos + 1:] + else: + while Name.startswith('*'): + Value += ' ' + '*' + Name = Name.lstrip('*').strip() + + if Name.find('[') != -1: + LBPos = Name.find('[') + RBPos = Name.rfind(']') + Value += Name[LBPos : RBPos + 1] + Name = Name[0 : LBPos] + + IdTd = DataClass.IdentifierClass(-1, Modifier, '', Name, Value, DataClass.MODEL_IDENTIFIER_TYPEDEF, -1, -1, td.StartPos[0],td.StartPos[1],td.EndPos[0],td.EndPos[1]) + IdList.append(IdTd) + + for funcCall in FileProfile.FunctionCallingList: + IdFC = DataClass.IdentifierClass(-1, '', '', funcCall.FuncName, funcCall.ParamList, DataClass.MODEL_IDENTIFIER_FUNCTION_CALLING, -1, -1, funcCall.StartPos[0],funcCall.StartPos[1],funcCall.EndPos[0],funcCall.EndPos[1]) + IdList.append(IdFC) + return IdList + +def StripNonAlnumChars(Str): + StrippedStr = '' + for Char in Str: + if Char.isalnum(): + StrippedStr += Char + return StrippedStr + +def GetParamList(FuncDeclarator, FuncNameLine = 0, FuncNameOffset = 0): + FuncDeclarator = StripComments(FuncDeclarator) + ParamIdList = [] + #DeclSplitList = FuncDeclarator.split('(') + LBPos = FuncDeclarator.find('(') + #if len(DeclSplitList) < 2: + if LBPos == -1: + return ParamIdList + #FuncName = DeclSplitList[0] + FuncName = FuncDeclarator[0:LBPos] + #ParamStr = DeclSplitList[1].rstrip(')') + ParamStr = FuncDeclarator[LBPos + 1:].rstrip(')') + LineSkipped = 0 + OffsetSkipped = 0 + TailChar = FuncName[-1] + while not TailChar.isalpha() and TailChar != '_': + + if TailChar == '\n': + FuncName = FuncName.rstrip('\r\n').rstrip('\n') + LineSkipped += 1 + OffsetSkipped = 0 + elif TailChar == '\r': + FuncName = FuncName.rstrip('\r') + LineSkipped += 1 + OffsetSkipped = 0 + elif TailChar == ' ': + FuncName = FuncName.rstrip(' ') + OffsetSkipped += 1 + elif TailChar == '\t': + FuncName = FuncName.rstrip('\t') + OffsetSkipped += 8 + else: + FuncName = FuncName[:-1] + TailChar = FuncName[-1] + + OffsetSkipped += 1 #skip '(' + + for p in ParamStr.split(','): + ListP = p.split() + if len(ListP) == 0: + continue + ParamName = ListP[-1] + DeclText = ParamName.strip() + RightSpacePos = p.rfind(ParamName) + ParamModifier = p[0:RightSpacePos] + if ParamName == 'OPTIONAL': + if ParamModifier == '': + ParamModifier += ' ' + 'OPTIONAL' + DeclText = '' + else: + ParamName = ListP[-2] + DeclText = ParamName.strip() + RightSpacePos = p.rfind(ParamName) + ParamModifier = p[0:RightSpacePos] + ParamModifier += 'OPTIONAL' + while DeclText.startswith('*'): + ParamModifier += ' ' + '*' + DeclText = DeclText.lstrip('*').strip() + ParamName = DeclText + # ignore array length if exists. + LBIndex = ParamName.find('[') + if LBIndex != -1: + ParamName = ParamName[0:LBIndex] + + Start = RightSpacePos + Index = 0 + PreChar = '' + while Index < Start: + FirstChar = p[Index] + + if FirstChar == '\r': + Index += 1 + LineSkipped += 1 + OffsetSkipped = 0 + elif FirstChar == '\n': + Index += 1 + if PreChar != '\r': + LineSkipped += 1 + OffsetSkipped = 0 + elif FirstChar == ' ': + Index += 1 + OffsetSkipped += 1 + elif FirstChar == '\t': + Index += 1 + OffsetSkipped += 8 + else: + Index += 1 + OffsetSkipped += 1 + PreChar = FirstChar + + ParamBeginLine = FuncNameLine + LineSkipped + ParamBeginOffset = FuncNameOffset + OffsetSkipped + + Index = Start + len(ParamName) + PreChar = '' + while Index < len(p): + FirstChar = p[Index] + + if FirstChar == '\r': + Index += 1 + LineSkipped += 1 + OffsetSkipped = 0 + elif FirstChar == '\n': + Index += 1 + if PreChar != '\r': + LineSkipped += 1 + OffsetSkipped = 0 + elif FirstChar == ' ': + Index += 1 + OffsetSkipped += 1 + elif FirstChar == '\t': + Index += 1 + OffsetSkipped += 8 + else: + Index += 1 + OffsetSkipped += 1 + PreChar = FirstChar + + ParamEndLine = FuncNameLine + LineSkipped + ParamEndOffset = FuncNameOffset + OffsetSkipped + if ParamName != '...': + ParamName = StripNonAlnumChars(ParamName) + IdParam = DataClass.IdentifierClass(-1, ParamModifier, '', ParamName, '', DataClass.MODEL_IDENTIFIER_PARAMETER, -1, -1, ParamBeginLine, ParamBeginOffset, ParamEndLine, ParamEndOffset) + ParamIdList.append(IdParam) + + OffsetSkipped += 1 #skip ',' + + return ParamIdList + +def GetFunctionList(): + FuncObjList = [] + for FuncDef in FileProfile.FunctionDefinitionList: + ParamIdList = [] + DeclText = FuncDef.Declarator.lstrip() + FuncNameStartLine = FuncDef.NamePos[0] + FuncNameStartColumn = FuncDef.NamePos[1] + FirstChar = DeclText[0] + while not FirstChar.isalpha() and FirstChar != '_': + if FirstChar == '*': + FuncDef.Modifier += '*' + FuncNameStartColumn += 1 + DeclText = DeclText.lstrip('*') + elif FirstChar == '\r': + DeclText = DeclText.lstrip('\r\n').lstrip('\r') + FuncNameStartLine += 1 + FuncNameStartColumn = 0 + elif FirstChar == '\n': + DeclText = DeclText.lstrip('\n') + FuncNameStartLine += 1 + FuncNameStartColumn = 0 + elif FirstChar == ' ': + DeclText = DeclText.lstrip(' ') + FuncNameStartColumn += 1 + elif FirstChar == '\t': + DeclText = DeclText.lstrip('\t') + FuncNameStartColumn += 8 + else: + DeclText = DeclText[1:] + FuncNameStartColumn += 1 + FirstChar = DeclText[0] + + FuncDef.Declarator = DeclText + DeclSplitList = FuncDef.Declarator.split('(') + if len(DeclSplitList) < 2: + continue + + FuncName = DeclSplitList[0] + FuncNamePartList = FuncName.split() + if len(FuncNamePartList) > 1: + FuncName = FuncNamePartList[-1] + NameStart = DeclSplitList[0].rfind(FuncName) + if NameStart > 0: + FuncDef.Modifier += ' ' + DeclSplitList[0][0:NameStart] + Index = 0 + PreChar = '' + while Index < NameStart: + FirstChar = DeclSplitList[0][Index] + if DeclSplitList[0][Index:].startswith('EFIAPI'): + Index += 6 + FuncNameStartColumn += 6 + PreChar = '' + continue + elif FirstChar == '\r': + Index += 1 + FuncNameStartLine += 1 + FuncNameStartColumn = 0 + elif FirstChar == '\n': + Index += 1 + if PreChar != '\r': + FuncNameStartLine += 1 + FuncNameStartColumn = 0 + elif FirstChar == ' ': + Index += 1 + FuncNameStartColumn += 1 + elif FirstChar == '\t': + Index += 1 + FuncNameStartColumn += 8 + else: + Index += 1 + FuncNameStartColumn += 1 + PreChar = FirstChar + + FuncObj = DataClass.FunctionClass(-1, FuncDef.Declarator, FuncDef.Modifier, FuncName.strip(), '', FuncDef.StartPos[0],FuncDef.StartPos[1],FuncDef.EndPos[0],FuncDef.EndPos[1], FuncDef.LeftBracePos[0], FuncDef.LeftBracePos[1], -1, ParamIdList, [], FuncNameStartLine, FuncNameStartColumn) + FuncObjList.append(FuncObj) + + return FuncObjList + +def GetFileModificationTimeFromDB(FullFileName): + TimeValue = 0.0 + Db = GetDB() + SqlStatement = """ select TimeStamp + from File + where FullPath = \'%s\' + """ % (FullFileName) + ResultSet = Db.TblFile.Exec(SqlStatement) + for Result in ResultSet: + TimeValue = Result[0] + return TimeValue + +def CollectSourceCodeDataIntoDB(RootDir): + FileObjList = [] + tuple = os.walk(RootDir) + IgnoredPattern = GetIgnoredDirListPattern() + ParseErrorFileList = [] + + for dirpath, dirnames, filenames in tuple: + if IgnoredPattern.match(dirpath.upper()): + continue + + for Dir in dirnames: + Dirname = os.path.join(dirpath, Dir) + if os.path.islink(Dirname): + Dirname = os.path.realpath(Dirname) + if os.path.isdir(Dirname): + # symlinks to directories are treated as directories + dirnames.remove(Dir) + dirnames.append(Dirname) + + for f in filenames: + FullName = os.path.normpath(os.path.join(dirpath, f)) + if os.path.splitext(f)[1] in ('.h', '.c'): + EdkLogger.info("Parsing " + FullName) + model = f.endswith('c') and DataClass.MODEL_FILE_C or DataClass.MODEL_FILE_H + collector = CodeFragmentCollector.CodeFragmentCollector(FullName) + try: + collector.ParseFile() + except UnicodeError: + ParseErrorFileList.append(FullName) + collector.CleanFileProfileBuffer() + collector.ParseFileWithClearedPPDirective() +# collector.PrintFragments() + BaseName = os.path.basename(f) + DirName = os.path.dirname(FullName) + Ext = os.path.splitext(f)[1].lstrip('.') + ModifiedTime = os.path.getmtime(FullName) + FileObj = DataClass.FileClass(-1, BaseName, Ext, DirName, FullName, model, ModifiedTime, GetFunctionList(), GetIdentifierList(), []) + FileObjList.append(FileObj) + collector.CleanFileProfileBuffer() + + if len(ParseErrorFileList) > 0: + EdkLogger.info("Found unrecoverable error during parsing:\n\t%s\n" % "\n\t".join(ParseErrorFileList)) + + Db = GetDB() + for file in FileObjList: + Db.InsertOneFile(file) + + Db.UpdateIdentifierBelongsToFunction() + +def GetTableID(FullFileName, ErrorMsgList = None): + if ErrorMsgList == None: + ErrorMsgList = [] + + Db = GetDB() + SqlStatement = """ select ID + from File + where FullPath like '%s' + """ % FullFileName + + ResultSet = Db.TblFile.Exec(SqlStatement) + + FileID = -1 + for Result in ResultSet: + if FileID != -1: + ErrorMsgList.append('Duplicate file ID found in DB for file %s' % FullFileName) + return -2 + FileID = Result[0] + if FileID == -1: + ErrorMsgList.append('NO file ID found in DB for file %s' % FullFileName) + return -1 + return FileID + +def GetIncludeFileList(FullFileName): + IFList = IncludeFileListDict.get(FullFileName) + if IFList != None: + return IFList + + FileID = GetTableID(FullFileName) + if FileID < 0: + return [] + + Db = GetDB() + FileTable = 'Identifier' + str(FileID) + SqlStatement = """ select Value + from %s + where Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_INCLUDE) + ResultSet = Db.TblFile.Exec(SqlStatement) + IncludeFileListDict[FullFileName] = ResultSet + return ResultSet + +def GetFullPathOfIncludeFile(Str, IncludePathList): + for IncludePath in IncludePathList: + FullPath = os.path.join(IncludePath, Str) + FullPath = os.path.normpath(FullPath) + if os.path.exists(FullPath): + return FullPath + return None + +def GetAllIncludeFiles(FullFileName): + if AllIncludeFileListDict.get(FullFileName) != None: + return AllIncludeFileListDict.get(FullFileName) + + FileDirName = os.path.dirname(FullFileName) + IncludePathList = IncludePathListDict.get(FileDirName) + if IncludePathList == None: + IncludePathList = MetaDataParser.GetIncludeListOfFile(EccGlobalData.gWorkspace, FullFileName, GetDB()) + if FileDirName not in IncludePathList: + IncludePathList.insert(0, FileDirName) + IncludePathListDict[FileDirName] = IncludePathList + IncludeFileQueue = [] + for IncludeFile in GetIncludeFileList(FullFileName): + FileName = IncludeFile[0].lstrip('#').strip() + FileName = FileName.lstrip('include').strip() + FileName = FileName.strip('\"') + FileName = FileName.lstrip('<').rstrip('>').strip() + FullPath = GetFullPathOfIncludeFile(FileName, IncludePathList) + if FullPath != None: + IncludeFileQueue.append(FullPath) + + i = 0 + while i < len(IncludeFileQueue): + for IncludeFile in GetIncludeFileList(IncludeFileQueue[i]): + FileName = IncludeFile[0].lstrip('#').strip() + FileName = FileName.lstrip('include').strip() + FileName = FileName.strip('\"') + FileName = FileName.lstrip('<').rstrip('>').strip() + FullPath = GetFullPathOfIncludeFile(FileName, IncludePathList) + if FullPath != None and FullPath not in IncludeFileQueue: + IncludeFileQueue.insert(i + 1, FullPath) + i += 1 + + AllIncludeFileListDict[FullFileName] = IncludeFileQueue + return IncludeFileQueue + +def GetPredicateListFromPredicateExpStr(PES): + + PredicateList = [] + i = 0 + PredicateBegin = 0 + #PredicateEnd = 0 + LogicOpPos = -1 + p = GetFuncDeclPattern() + while i < len(PES) - 1: + if (PES[i].isalnum() or PES[i] == '_' or PES[i] == '*') and LogicOpPos > PredicateBegin: + PredicateBegin = i + if (PES[i] == '&' and PES[i+1] == '&') or (PES[i] == '|' and PES[i+1] == '|'): + LogicOpPos = i + Exp = PES[PredicateBegin:i].strip() + # Exp may contain '.' or '->' + TmpExp = Exp.replace('.', '').replace('->', '') + if p.match(TmpExp): + PredicateList.append(Exp) + else: + PredicateList.append(Exp.rstrip(';').rstrip(')').strip()) + i += 1 + + if PredicateBegin > LogicOpPos: + while PredicateBegin < len(PES): + if PES[PredicateBegin].isalnum() or PES[PredicateBegin] == '_' or PES[PredicateBegin] == '*': + break + PredicateBegin += 1 + Exp = PES[PredicateBegin:len(PES)].strip() + # Exp may contain '.' or '->' + TmpExp = Exp.replace('.', '').replace('->', '') + if p.match(TmpExp): + PredicateList.append(Exp) + else: + PredicateList.append(Exp.rstrip(';').rstrip(')').strip()) + return PredicateList + +def GetCNameList(Lvalue, StarList = []): + Lvalue += ' ' + i = 0 + SearchBegin = 0 + VarStart = -1 + VarEnd = -1 + VarList = [] + + while SearchBegin < len(Lvalue): + while i < len(Lvalue): + if Lvalue[i].isalnum() or Lvalue[i] == '_': + if VarStart == -1: + VarStart = i + VarEnd = i + i += 1 + elif VarEnd != -1: + VarList.append(Lvalue[VarStart:VarEnd+1]) + i += 1 + break + else: + if VarStart == -1 and Lvalue[i] == '*': + StarList.append('*') + i += 1 + if VarEnd == -1: + break + + + DotIndex = Lvalue[VarEnd:].find('.') + ArrowIndex = Lvalue[VarEnd:].find('->') + if DotIndex == -1 and ArrowIndex == -1: + break + elif DotIndex == -1 and ArrowIndex != -1: + SearchBegin = VarEnd + ArrowIndex + elif ArrowIndex == -1 and DotIndex != -1: + SearchBegin = VarEnd + DotIndex + else: + SearchBegin = VarEnd + ((DotIndex < ArrowIndex) and DotIndex or ArrowIndex) + + i = SearchBegin + VarStart = -1 + VarEnd = -1 + + return VarList + +def SplitPredicateByOp(Str, Op, IsFuncCalling = False): + + Name = Str.strip() + Value = None + + if IsFuncCalling: + Index = 0 + LBFound = False + UnmatchedLBCount = 0 + while Index < len(Str): + while not LBFound and Str[Index] != '_' and not Str[Index].isalnum(): + Index += 1 + + while not LBFound and (Str[Index].isalnum() or Str[Index] == '_'): + Index += 1 + # maybe type-cast at the begining, skip it. + RemainingStr = Str[Index:].lstrip() + if RemainingStr.startswith(')') and not LBFound: + Index += 1 + continue + + if RemainingStr.startswith('(') and not LBFound: + LBFound = True + + if Str[Index] == '(': + UnmatchedLBCount += 1 + Index += 1 + continue + + if Str[Index] == ')': + UnmatchedLBCount -= 1 + Index += 1 + if UnmatchedLBCount == 0: + break + continue + + Index += 1 + + if UnmatchedLBCount > 0: + return [Name] + + IndexInRemainingStr = Str[Index:].find(Op) + if IndexInRemainingStr == -1: + return [Name] + + Name = Str[0:Index + IndexInRemainingStr].strip() + Value = Str[Index+IndexInRemainingStr+len(Op):].strip() + return [Name, Value] + + TmpStr = Str.rstrip(';').rstrip(')') + while True: + Index = TmpStr.rfind(Op) + if Index == -1: + return [Name] + + if Str[Index - 1].isalnum() or Str[Index - 1].isspace() or Str[Index - 1] == ')': + Name = Str[0:Index].strip() + Value = Str[Index + len(Op):].strip() + return [Name, Value] + + TmpStr = Str[0:Index - 1] + +def SplitPredicateStr(Str): + IsFuncCalling = False + p = GetFuncDeclPattern() + TmpStr = Str.replace('.', '').replace('->', '') + if p.match(TmpStr): + IsFuncCalling = True + + PredPartList = SplitPredicateByOp(Str, '==', IsFuncCalling) + if len(PredPartList) > 1: + return [PredPartList, '=='] + + PredPartList = SplitPredicateByOp(Str, '!=', IsFuncCalling) + if len(PredPartList) > 1: + return [PredPartList, '!='] + + PredPartList = SplitPredicateByOp(Str, '>=', IsFuncCalling) + if len(PredPartList) > 1: + return [PredPartList, '>='] + + PredPartList = SplitPredicateByOp(Str, '<=', IsFuncCalling) + if len(PredPartList) > 1: + return [PredPartList, '<='] + + PredPartList = SplitPredicateByOp(Str, '>', IsFuncCalling) + if len(PredPartList) > 1: + return [PredPartList, '>'] + + PredPartList = SplitPredicateByOp(Str, '<', IsFuncCalling) + if len(PredPartList) > 1: + return [PredPartList, '<'] + + return [[Str, None], None] + +def GetFuncContainsPE(ExpLine, ResultSet): + for Result in ResultSet: + if Result[0] < ExpLine and Result[1] > ExpLine: + return Result + return None + +def PatternInModifier(Modifier, SubStr): + PartList = Modifier.split() + for Part in PartList: + if Part == SubStr: + return True + return False + +def GetDataTypeFromModifier(ModifierStr): + MList = ModifierStr.split() + for M in MList: + if M in EccGlobalData.gConfig.ModifierList: + MList.remove(M) + # remove array sufix + if M.startswith('['): + MList.remove(M) + + ReturnType = '' + for M in MList: + ReturnType += M + ' ' + + ReturnType = ReturnType.strip() + if len(ReturnType) == 0: + ReturnType = 'VOID' + return ReturnType + +def DiffModifier(Str1, Str2): + PartList1 = Str1.split() + PartList2 = Str2.split() + if PartList1 == PartList2: + return False + else: + return True + +def GetTypedefDict(FullFileName): + + Dict = ComplexTypeDict.get(FullFileName) + if Dict != None: + return Dict + + FileID = GetTableID(FullFileName) + FileTable = 'Identifier' + str(FileID) + Db = GetDB() + SqlStatement = """ select Modifier, Name, Value, ID + from %s + where Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF) + ResultSet = Db.TblFile.Exec(SqlStatement) + + Dict = {} + for Result in ResultSet: + if len(Result[0]) == 0: + Dict[Result[1]] = Result[2] + + IncludeFileList = GetAllIncludeFiles(FullFileName) + for F in IncludeFileList: + FileID = GetTableID(F) + if FileID < 0: + continue + + FileTable = 'Identifier' + str(FileID) + SqlStatement = """ select Modifier, Name, Value, ID + from %s + where Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF) + ResultSet = Db.TblFile.Exec(SqlStatement) + + for Result in ResultSet: + if not Result[2].startswith('FP ('): + Dict[Result[1]] = Result[2] + else: + if len(Result[0]) == 0: + Dict[Result[1]] = 'VOID' + else: + Dict[Result[1]] = GetDataTypeFromModifier(Result[0]) + + ComplexTypeDict[FullFileName] = Dict + return Dict + +def GetSUDict(FullFileName): + + Dict = SUDict.get(FullFileName) + if Dict != None: + return Dict + + FileID = GetTableID(FullFileName) + FileTable = 'Identifier' + str(FileID) + Db = GetDB() + SqlStatement = """ select Name, Value, ID + from %s + where Model = %d or Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_STRUCTURE, DataClass.MODEL_IDENTIFIER_UNION) + ResultSet = Db.TblFile.Exec(SqlStatement) + + Dict = {} + for Result in ResultSet: + if len(Result[1]) > 0: + Dict[Result[0]] = Result[1] + + IncludeFileList = GetAllIncludeFiles(FullFileName) + for F in IncludeFileList: + FileID = GetTableID(F) + if FileID < 0: + continue + + FileTable = 'Identifier' + str(FileID) + SqlStatement = """ select Name, Value, ID + from %s + where Model = %d or Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_STRUCTURE, DataClass.MODEL_IDENTIFIER_UNION) + ResultSet = Db.TblFile.Exec(SqlStatement) + + for Result in ResultSet: + if len(Result[1]) > 0: + Dict[Result[0]] = Result[1] + + SUDict[FullFileName] = Dict + return Dict + +def StripComments(Str): + Str += ' ' + ListFromStr = list(Str) + + InComment = False + DoubleSlashComment = False + Index = 0 + while Index < len(ListFromStr): + # meet new line, then no longer in a comment for // + if ListFromStr[Index] == '\n': + if InComment and DoubleSlashComment: + InComment = False + DoubleSlashComment = False + Index += 1 + # check for */ comment end + elif InComment and not DoubleSlashComment and ListFromStr[Index] == '*' and ListFromStr[Index+1] == '/': + ListFromStr[Index] = ' ' + Index += 1 + ListFromStr[Index] = ' ' + Index += 1 + InComment = False + # set comments to spaces + elif InComment: + ListFromStr[Index] = ' ' + Index += 1 + # check for // comment + elif ListFromStr[Index] == '/' and ListFromStr[Index+1] == '/' and ListFromStr[Index+2] != '\n': + InComment = True + DoubleSlashComment = True + + # check for /* comment start + elif ListFromStr[Index] == '/' and ListFromStr[Index+1] == '*': + ListFromStr[Index] = ' ' + Index += 1 + ListFromStr[Index] = ' ' + Index += 1 + InComment = True + else: + Index += 1 + + # restore from List to String + Str = "".join(ListFromStr) + Str = Str.rstrip(' ') + + return Str + +def GetFinalTypeValue(Type, FieldName, TypedefDict, SUDict): + Value = TypedefDict.get(Type) + if Value == None: + Value = SUDict.get(Type) + if Value == None: + return None + + LBPos = Value.find('{') + while LBPos == -1: + FTList = Value.split() + for FT in FTList: + if FT not in ('struct', 'union'): + Value = TypedefDict.get(FT) + if Value == None: + Value = SUDict.get(FT) + break + + if Value == None: + return None + + LBPos = Value.find('{') + +# RBPos = Value.find('}') + Fields = Value[LBPos + 1:] + Fields = StripComments(Fields) + FieldsList = Fields.split(';') + for Field in FieldsList: + Field = Field.strip() + Index = Field.rfind(FieldName) + if Index < 1: + continue + if not Field[Index - 1].isalnum(): + if Index + len(FieldName) == len(Field): + Type = GetDataTypeFromModifier(Field[0:Index]) + return Type.strip() + else: + # For the condition that the field in struct is an array with [] sufixes... + if not Field[Index + len(FieldName)].isalnum(): + Type = GetDataTypeFromModifier(Field[0:Index]) + return Type.strip() + + return None + +def GetRealType(Type, TypedefDict, TargetType = None): + if TargetType != None and Type == TargetType: + return Type + while TypedefDict.get(Type): + Type = TypedefDict.get(Type) + if TargetType != None and Type == TargetType: + return Type + return Type + +def GetTypeInfo(RefList, Modifier, FullFileName, TargetType = None): + TypedefDict = GetTypedefDict(FullFileName) + SUDict = GetSUDict(FullFileName) + Type = GetDataTypeFromModifier(Modifier).replace('*', '').strip() + + Type = Type.split()[-1] + Index = 0 + while Index < len(RefList): + FieldName = RefList[Index] + FromType = GetFinalTypeValue(Type, FieldName, TypedefDict, SUDict) + if FromType == None: + return None + # we want to determine the exact type. + if TargetType != None: + Type = FromType.split()[0] + # we only want to check if it is a pointer + else: + Type = FromType + if Type.find('*') != -1 and Index == len(RefList)-1: + return Type + Type = FromType.split()[0] + + Index += 1 + + Type = GetRealType(Type, TypedefDict, TargetType) + + return Type + +def GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall = False, TargetType = None, StarList = None): + + PredVar = PredVarList[0] + FileID = GetTableID(FullFileName) + + Db = GetDB() + FileTable = 'Identifier' + str(FileID) + # search variable in include files + + # it is a function call, search function declarations and definitions + if IsFuncCall: + SqlStatement = """ select Modifier, ID + from %s + where Model = %d and Value = \'%s\' + """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION, PredVar) + ResultSet = Db.TblFile.Exec(SqlStatement) + + for Result in ResultSet: + Type = GetDataTypeFromModifier(Result[0]).split()[-1] + TypedefDict = GetTypedefDict(FullFileName) + Type = GetRealType(Type, TypedefDict, TargetType) + return Type + + IncludeFileList = GetAllIncludeFiles(FullFileName) + for F in IncludeFileList: + FileID = GetTableID(F) + if FileID < 0: + continue + + FileTable = 'Identifier' + str(FileID) + SqlStatement = """ select Modifier, ID + from %s + where Model = %d and Value = \'%s\' + """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION, PredVar) + ResultSet = Db.TblFile.Exec(SqlStatement) + + for Result in ResultSet: + Type = GetDataTypeFromModifier(Result[0]).split()[-1] + TypedefDict = GetTypedefDict(FullFileName) + Type = GetRealType(Type, TypedefDict, TargetType) + return Type + + FileID = GetTableID(FullFileName) + SqlStatement = """ select Modifier, ID + from Function + where BelongsToFile = %d and Name = \'%s\' + """ % (FileID, PredVar) + ResultSet = Db.TblFile.Exec(SqlStatement) + + for Result in ResultSet: + Type = GetDataTypeFromModifier(Result[0]).split()[-1] + TypedefDict = GetTypedefDict(FullFileName) + Type = GetRealType(Type, TypedefDict, TargetType) + return Type + + for F in IncludeFileList: + FileID = GetTableID(F) + if FileID < 0: + continue + + FileTable = 'Identifier' + str(FileID) + SqlStatement = """ select Modifier, ID + from Function + where BelongsToFile = %d and Name = \'%s\' + """ % (FileID, PredVar) + ResultSet = Db.TblFile.Exec(SqlStatement) + + for Result in ResultSet: + Type = GetDataTypeFromModifier(Result[0]).split()[-1] + TypedefDict = GetTypedefDict(FullFileName) + Type = GetRealType(Type, TypedefDict, TargetType) + return Type + + return None + + # really variable, search local variable first + SqlStatement = """ select Modifier, ID + from %s + where Model = %d and Name = \'%s\' and StartLine >= %d and StartLine <= %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, PredVar, FuncRecord[0], FuncRecord[1]) + ResultSet = Db.TblFile.Exec(SqlStatement) + VarFound = False + for Result in ResultSet: + if len(PredVarList) > 1: + Type = GetTypeInfo(PredVarList[1:], Result[0], FullFileName, TargetType) + return Type + else: +# Type = GetDataTypeFromModifier(Result[0]).split()[-1] + TypeList = GetDataTypeFromModifier(Result[0]).split() + Type = TypeList[-1] + if len(TypeList) > 1 and StarList != None: + for Star in StarList: + Type = Type.strip() + Type = Type.rstrip(Star) + # Get real type after de-reference pointers. + if len(Type.strip()) == 0: + Type = TypeList[-2] + TypedefDict = GetTypedefDict(FullFileName) + Type = GetRealType(Type, TypedefDict, TargetType) + return Type + + # search function parameters second + ParamList = GetParamList(FuncRecord[2]) + for Param in ParamList: + if Param.Name.strip() == PredVar: + if len(PredVarList) > 1: + Type = GetTypeInfo(PredVarList[1:], Param.Modifier, FullFileName, TargetType) + return Type + else: + TypeList = GetDataTypeFromModifier(Param.Modifier).split() + Type = TypeList[-1] + if len(TypeList) > 1 and StarList != None: + for Star in StarList: + Type = Type.strip() + Type = Type.rstrip(Star) + # Get real type after de-reference pointers. + if len(Type.strip()) == 0: + Type = TypeList[-2] + TypedefDict = GetTypedefDict(FullFileName) + Type = GetRealType(Type, TypedefDict, TargetType) + return Type + + # search global variable next + SqlStatement = """ select Modifier, ID + from %s + where Model = %d and Name = \'%s\' and BelongsToFunction = -1 + """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, PredVar) + ResultSet = Db.TblFile.Exec(SqlStatement) + + for Result in ResultSet: + if len(PredVarList) > 1: + Type = GetTypeInfo(PredVarList[1:], Result[0], FullFileName, TargetType) + return Type + else: + TypeList = GetDataTypeFromModifier(Result[0]).split() + Type = TypeList[-1] + if len(TypeList) > 1 and StarList != None: + for Star in StarList: + Type = Type.strip() + Type = Type.rstrip(Star) + # Get real type after de-reference pointers. + if len(Type.strip()) == 0: + Type = TypeList[-2] + TypedefDict = GetTypedefDict(FullFileName) + Type = GetRealType(Type, TypedefDict, TargetType) + return Type + + IncludeFileList = GetAllIncludeFiles(FullFileName) + for F in IncludeFileList: + FileID = GetTableID(F) + if FileID < 0: + continue + + FileTable = 'Identifier' + str(FileID) + SqlStatement = """ select Modifier, ID + from %s + where Model = %d and BelongsToFunction = -1 and Name = \'%s\' + """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, PredVar) + ResultSet = Db.TblFile.Exec(SqlStatement) + + for Result in ResultSet: + if len(PredVarList) > 1: + Type = GetTypeInfo(PredVarList[1:], Result[0], FullFileName, TargetType) + return Type + else: + TypeList = GetDataTypeFromModifier(Result[0]).split() + Type = TypeList[-1] + if len(TypeList) > 1 and StarList != None: + for Star in StarList: + Type = Type.strip() + Type = Type.rstrip(Star) + # Get real type after de-reference pointers. + if len(Type.strip()) == 0: + Type = TypeList[-2] + TypedefDict = GetTypedefDict(FullFileName) + Type = GetRealType(Type, TypedefDict, TargetType) + return Type + +def CheckFuncLayoutReturnType(FullFileName): + ErrorMsgList = [] + + FileID = GetTableID(FullFileName, ErrorMsgList) + if FileID < 0: + return ErrorMsgList + + Db = GetDB() + FileTable = 'Identifier' + str(FileID) + SqlStatement = """ select Modifier, ID, StartLine, StartColumn, EndLine, Value + from %s + where Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION) + ResultSet = Db.TblFile.Exec(SqlStatement) + for Result in ResultSet: + ReturnType = GetDataTypeFromModifier(Result[0]) + TypeStart = ReturnType.split()[0] + FuncName = Result[5] + if EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, FuncName): + continue + Index = Result[0].find(TypeStart) + if Index != 0 or Result[3] != 0: + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear at the start of line' % FuncName, FileTable, Result[1]) + + if Result[2] == Result[4]: + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear on its own line' % FuncName, FileTable, Result[1]) + + SqlStatement = """ select Modifier, ID, StartLine, StartColumn, FunNameStartLine, Name + from Function + where BelongsToFile = %d + """ % (FileID) + ResultSet = Db.TblFile.Exec(SqlStatement) + for Result in ResultSet: + ReturnType = GetDataTypeFromModifier(Result[0]) + TypeStart = ReturnType.split()[0] + FuncName = Result[5] + if EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, FuncName): + continue + Index = Result[0].find(ReturnType) + if Index != 0 or Result[3] != 0: + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear at the start of line' % FuncName, 'Function', Result[1]) + + if Result[2] == Result[4]: + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_RETURN_TYPE, '[%s] Return Type should appear on its own line' % FuncName, 'Function', Result[1]) + +def CheckFuncLayoutModifier(FullFileName): + ErrorMsgList = [] + + FileID = GetTableID(FullFileName, ErrorMsgList) + if FileID < 0: + return ErrorMsgList + + Db = GetDB() + FileTable = 'Identifier' + str(FileID) + SqlStatement = """ select Modifier, ID + from %s + where Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION) + ResultSet = Db.TblFile.Exec(SqlStatement) + for Result in ResultSet: + ReturnType = GetDataTypeFromModifier(Result[0]) + TypeStart = ReturnType.split()[0] +# if len(ReturnType) == 0: +# continue + Index = Result[0].find(TypeStart) + if Index != 0: + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER, '', FileTable, Result[1]) + + SqlStatement = """ select Modifier, ID + from Function + where BelongsToFile = %d + """ % (FileID) + ResultSet = Db.TblFile.Exec(SqlStatement) + for Result in ResultSet: + ReturnType = GetDataTypeFromModifier(Result[0]) + TypeStart = ReturnType.split()[0] +# if len(ReturnType) == 0: +# continue + Index = Result[0].find(TypeStart) + if Index != 0: + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_OPTIONAL_FUNCTIONAL_MODIFIER, '', 'Function', Result[1]) + +def CheckFuncLayoutName(FullFileName): + ErrorMsgList = [] + # Parameter variable format pattern. + Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$') + ParamIgnoreList = ('VOID', '...') + FileID = GetTableID(FullFileName, ErrorMsgList) + if FileID < 0: + return ErrorMsgList + + Db = GetDB() + FileTable = 'Identifier' + str(FileID) + SqlStatement = """ select Name, ID, EndColumn, Value + from %s + where Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION) + ResultSet = Db.TblFile.Exec(SqlStatement) + for Result in ResultSet: + FuncName = Result[3] + if EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, FuncName): + continue + if Result[2] != 0: + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Function name [%s] should appear at the start of a line' % FuncName, FileTable, Result[1]) + ParamList = GetParamList(Result[0]) + if len(ParamList) == 0: + continue + StartLine = 0 + for Param in ParamList: + if Param.StartLine <= StartLine: + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Parameter %s should be in its own line.' % Param.Name, FileTable, Result[1]) + if Param.StartLine - StartLine > 1: + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Empty line appears before Parameter %s.' % Param.Name, FileTable, Result[1]) + if not Pattern.match(Param.Name) and not Param.Name in ParamIgnoreList and not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Param.Name): + PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Parameter [%s] NOT follow naming convention.' % Param.Name, FileTable, Result[1]) + StartLine = Param.StartLine + + if not Result[0].endswith('\n )') and not Result[0].endswith('\r )'): + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, '\')\' should be on a new line and indented two spaces', FileTable, Result[1]) + + SqlStatement = """ select Modifier, ID, FunNameStartColumn, Name + from Function + where BelongsToFile = %d + """ % (FileID) + ResultSet = Db.TblFile.Exec(SqlStatement) + for Result in ResultSet: + FuncName = Result[3] + if EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, FuncName): + continue + if Result[2] != 0: + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Function name [%s] should appear at the start of a line' % FuncName, 'Function', Result[1]) + ParamList = GetParamList(Result[0]) + if len(ParamList) == 0: + continue + StartLine = 0 + for Param in ParamList: + if Param.StartLine <= StartLine: + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Parameter %s should be in its own line.' % Param.Name, 'Function', Result[1]) + if Param.StartLine - StartLine > 1: + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, 'Empty line appears before Parameter %s.' % Param.Name, 'Function', Result[1]) + if not Pattern.match(Param.Name) and not Param.Name in ParamIgnoreList and not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Param.Name): + PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Parameter [%s] NOT follow naming convention.' % Param.Name, FileTable, Result[1]) + StartLine = Param.StartLine + if not Result[0].endswith('\n )') and not Result[0].endswith('\r )'): + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_NAME, '\')\' should be on a new line and indented two spaces', 'Function', Result[1]) + +def CheckFuncLayoutPrototype(FullFileName): + ErrorMsgList = [] + + FileID = GetTableID(FullFileName, ErrorMsgList) + if FileID < 0: + return ErrorMsgList + + FileTable = 'Identifier' + str(FileID) + Db = GetDB() + SqlStatement = """ select Modifier, Header, Name, ID + from Function + where BelongsToFile = %d + """ % (FileID) + ResultSet = Db.TblFile.Exec(SqlStatement) + if len(ResultSet) == 0: + return ErrorMsgList + + FuncDefList = [] + for Result in ResultSet: + FuncDefList.append(Result) + + SqlStatement = """ select Modifier, Name, ID + from %s + where Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION) + ResultSet = Db.TblFile.Exec(SqlStatement) + FuncDeclList = [] + for Result in ResultSet: + FuncDeclList.append(Result) + + UndeclFuncList = [] + for FuncDef in FuncDefList: + FuncName = FuncDef[2].strip() + FuncModifier = FuncDef[0] + FuncDefHeader = FuncDef[1] + for FuncDecl in FuncDeclList: + LBPos = FuncDecl[1].find('(') + DeclName = FuncDecl[1][0:LBPos].strip() + DeclModifier = FuncDecl[0] + if DeclName == FuncName: + if DiffModifier(FuncModifier, DeclModifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, FuncName): + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Function [%s] modifier different with prototype.' % FuncName, 'Function', FuncDef[3]) + ParamListOfDef = GetParamList(FuncDefHeader) + ParamListOfDecl = GetParamList(FuncDecl[1]) + if len(ParamListOfDef) != len(ParamListOfDecl): + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Parameter number different.', 'Function', FuncDef[3]) + break + + Index = 0 + while Index < len(ParamListOfDef): + if DiffModifier(ParamListOfDef[Index].Modifier, ParamListOfDecl[Index].Modifier): + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Parameter %s has different modifier with prototype.' % ParamListOfDef[Index].Name, 'Function', FuncDef[3]) + Index += 1 + break + else: + UndeclFuncList.append(FuncDef) + + IncludeFileList = GetAllIncludeFiles(FullFileName) + FuncDeclList = [] + for F in IncludeFileList: + FileID = GetTableID(F, ErrorMsgList) + if FileID < 0: + continue + + FileTable = 'Identifier' + str(FileID) + SqlStatement = """ select Modifier, Name, ID + from %s + where Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION) + ResultSet = Db.TblFile.Exec(SqlStatement) + + for Result in ResultSet: + FuncDeclList.append(Result) + + for FuncDef in UndeclFuncList: + FuncName = FuncDef[2].strip() + FuncModifier = FuncDef[0] + FuncDefHeader = FuncDef[1] + for FuncDecl in FuncDeclList: + LBPos = FuncDecl[1].find('(') + DeclName = FuncDecl[1][0:LBPos].strip() + DeclModifier = FuncDecl[0] + if DeclName == FuncName: + if DiffModifier(FuncModifier, DeclModifier) and not EccGlobalData.gException.IsException(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, FuncName): + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Function [%s] modifier different with prototype.' % FuncName, 'Function', FuncDef[3]) + ParamListOfDef = GetParamList(FuncDefHeader) + ParamListOfDecl = GetParamList(FuncDecl[1]) + if len(ParamListOfDef) != len(ParamListOfDecl): + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Parameter number different.', 'Function', FuncDef[3]) + break + + Index = 0 + while Index < len(ParamListOfDef): + if DiffModifier(ParamListOfDef[Index].Modifier, ParamListOfDecl[Index].Modifier): + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_PROTO_TYPE, 'Parameter %s has different modifier with prototype.' % ParamListOfDef[Index].Name, 'Function', FuncDef[3]) + Index += 1 + break + +def CheckFuncLayoutBody(FullFileName): + ErrorMsgList = [] + + FileID = GetTableID(FullFileName, ErrorMsgList) + if FileID < 0: + return ErrorMsgList + + FileTable = 'Identifier' + str(FileID) + Db = GetDB() + SqlStatement = """ select BodyStartColumn, EndColumn, ID + from Function + where BelongsToFile = %d + """ % (FileID) + ResultSet = Db.TblFile.Exec(SqlStatement) + if len(ResultSet) == 0: + return ErrorMsgList + for Result in ResultSet: + if Result[0] != 0: + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY, 'open brace should be at the very beginning of a line.', 'Function', Result[2]) + if Result[1] != 0: + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_FUNCTION_BODY, 'close brace should be at the very beginning of a line.', 'Function', Result[2]) + +def CheckFuncLayoutLocalVariable(FullFileName): + ErrorMsgList = [] + + FileID = GetTableID(FullFileName, ErrorMsgList) + if FileID < 0: + return ErrorMsgList + + Db = GetDB() + FileTable = 'Identifier' + str(FileID) + SqlStatement = """ select ID + from Function + where BelongsToFile = %d + """ % (FileID) + ResultSet = Db.TblFile.Exec(SqlStatement) + if len(ResultSet) == 0: + return ErrorMsgList + FL = [] + for Result in ResultSet: + FL.append(Result) + + for F in FL: + SqlStatement = """ select Name, Value, ID + from %s + where Model = %d and BelongsToFunction = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE, F[0]) + ResultSet = Db.TblFile.Exec(SqlStatement) + if len(ResultSet) == 0: + continue + + for Result in ResultSet: + if len(Result[1]) > 0: + PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE, 'Variable Name: %s' % Result[0], FileTable, Result[2]) + +def CheckMemberVariableFormat(Name, Value, FileTable, TdId, ModelId): + ErrMsgList = [] + # Member variable format pattern. + Pattern = re.compile(r'^[A-Z]+\S*[a-z]\S*$') + + LBPos = Value.find('{') + RBPos = Value.rfind('}') + if LBPos == -1 or RBPos == -1: + return ErrMsgList + + Fields = Value[LBPos + 1 : RBPos] + Fields = StripComments(Fields).strip() + NestPos = Fields.find ('struct') + if NestPos != -1 and (NestPos + len('struct') < len(Fields)): + if not Fields[NestPos + len('struct') + 1].isalnum(): + if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name): + PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested struct in [%s].' % (Name), FileTable, TdId) + return ErrMsgList + NestPos = Fields.find ('union') + if NestPos != -1 and (NestPos + len('union') < len(Fields)): + if not Fields[NestPos + len('union') + 1].isalnum(): + if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name): + PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested union in [%s].' % (Name), FileTable, TdId) + return ErrMsgList + NestPos = Fields.find ('enum') + if NestPos != -1 and (NestPos + len('enum') < len(Fields)): + if not Fields[NestPos + len('enum') + 1].isalnum(): + if not EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, Name): + PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NESTED_STRUCTURE, 'Nested enum in [%s].' % (Name), FileTable, TdId) + return ErrMsgList + + if ModelId == DataClass.MODEL_IDENTIFIER_ENUMERATE: + FieldsList = Fields.split(',') + # deal with enum is pre-assigned a value by function call ( , , , ...) + QuoteCount = 0 + Index = 0 + RemoveCurrentElement = False + while Index < len(FieldsList): + Field = FieldsList[Index] + + if Field.find('(') != -1: + QuoteCount += 1 + RemoveCurrentElement = True + Index += 1 + continue + + if Field.find(')') != -1 and QuoteCount > 0: + QuoteCount -= 1 + + if RemoveCurrentElement: + FieldsList.remove(Field) + if QuoteCount == 0: + RemoveCurrentElement = False + continue + + if QuoteCount == 0: + RemoveCurrentElement = False + + Index += 1 + else: + FieldsList = Fields.split(';') + + for Field in FieldsList: + Field = Field.strip() + if Field == '': + continue + # For the condition that the field in struct is an array with [] sufixes... + if Field[-1] == ']': + LBPos = Field.find('[') + Field = Field[0:LBPos] + # For the condition that bit field ": Number" + if Field.find(':') != -1: + ColonPos = Field.find(':') + Field = Field[0:ColonPos] + + Field = Field.strip() + if Field == '': + continue + # Enum could directly assign value to variable + Field = Field.split('=')[0].strip() + TokenList = Field.split() + # Remove pointers before variable + if not Pattern.match(TokenList[-1].lstrip('*')): + ErrMsgList.append(TokenList[-1].lstrip('*')) + + return ErrMsgList + +def CheckDeclTypedefFormat(FullFileName, ModelId): + ErrorMsgList = [] + + FileID = GetTableID(FullFileName, ErrorMsgList) + if FileID < 0: + return ErrorMsgList + + Db = GetDB() + FileTable = 'Identifier' + str(FileID) + SqlStatement = """ select Name, StartLine, EndLine, ID, Value + from %s + where Model = %d + """ % (FileTable, ModelId) + ResultSet = Db.TblFile.Exec(SqlStatement) + ResultList = [] + for Result in ResultSet: + ResultList.append(Result) + + ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_ALL + if ModelId == DataClass.MODEL_IDENTIFIER_STRUCTURE: + ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_STRUCTURE_DECLARATION + elif ModelId == DataClass.MODEL_IDENTIFIER_ENUMERATE: + ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_ENUMERATED_TYPE + elif ModelId == DataClass.MODEL_IDENTIFIER_UNION: + ErrorType = ERROR_DECLARATION_DATA_TYPE_CHECK_UNION_TYPE + + SqlStatement = """ select Modifier, Name, Value, StartLine, EndLine, ID + from %s + where Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF) + TdSet = Db.TblFile.Exec(SqlStatement) + TdList = [] + for Td in TdSet: + TdList.append(Td) + # Check member variable name format that from typedefs of ONLY this file. + for Td in TdList: + Name = Td[1].strip() + Value = Td[2].strip() + if Value.startswith('enum'): + ValueModelId = DataClass.MODEL_IDENTIFIER_ENUMERATE + elif Value.startswith('struct'): + ValueModelId = DataClass.MODEL_IDENTIFIER_STRUCTURE + elif Value.startswith('union'): + ValueModelId = DataClass.MODEL_IDENTIFIER_UNION + else: + continue + + if ValueModelId != ModelId: + continue + # Check member variable format. + ErrMsgList = CheckMemberVariableFormat(Name, Value, FileTable, Td[5], ModelId) + for ErrMsg in ErrMsgList: + if EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Name+'.'+ErrMsg): + continue + PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Member variable [%s] NOT follow naming convention.' % (Name+'.'+ErrMsg), FileTable, Td[5]) + + # First check in current file to see whether struct/union/enum is typedef-ed. + UntypedefedList = [] + for Result in ResultList: + # Check member variable format. + Name = Result[0].strip() + Value = Result[4].strip() + if Value.startswith('enum'): + ValueModelId = DataClass.MODEL_IDENTIFIER_ENUMERATE + elif Value.startswith('struct'): + ValueModelId = DataClass.MODEL_IDENTIFIER_STRUCTURE + elif Value.startswith('union'): + ValueModelId = DataClass.MODEL_IDENTIFIER_UNION + else: + continue + + if ValueModelId != ModelId: + continue + ErrMsgList = CheckMemberVariableFormat(Name, Value, FileTable, Result[3], ModelId) + for ErrMsg in ErrMsgList: + if EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, Result[0]+'.'+ErrMsg): + continue + PrintErrorMsg(ERROR_NAMING_CONVENTION_CHECK_VARIABLE_NAME, 'Member variable [%s] NOT follow naming convention.' % (Result[0]+'.'+ErrMsg), FileTable, Result[3]) + # Check whether it is typedefed. + Found = False + for Td in TdList: + # skip function pointer + if len(Td[0]) > 0: + continue + if Result[1] >= Td[3] and Td[4] >= Result[2]: + Found = True + if not Td[1].isupper(): + PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5]) + if Result[0] in Td[2].split(): + Found = True + if not Td[1].isupper(): + PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5]) + if Found: + break + + if not Found: + UntypedefedList.append(Result) + continue + + if len(UntypedefedList) == 0: + return + + IncludeFileList = GetAllIncludeFiles(FullFileName) + TdList = [] + for F in IncludeFileList: + FileID = GetTableID(F, ErrorMsgList) + if FileID < 0: + continue + + IncludeFileTable = 'Identifier' + str(FileID) + SqlStatement = """ select Modifier, Name, Value, StartLine, EndLine, ID + from %s + where Model = %d + """ % (IncludeFileTable, DataClass.MODEL_IDENTIFIER_TYPEDEF) + ResultSet = Db.TblFile.Exec(SqlStatement) + TdList.extend(ResultSet) + + for Result in UntypedefedList: + + # Check whether it is typedefed. + Found = False + for Td in TdList: + + if len(Td[0]) > 0: + continue + if Result[1] >= Td[3] and Td[4] >= Result[2]: + Found = True + if not Td[1].isupper(): + PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5]) + if Result[0] in Td[2].split(): + Found = True + if not Td[1].isupper(): + PrintErrorMsg(ErrorType, 'Typedef should be UPPER case', FileTable, Td[5]) + if Found: + break + + if not Found: + PrintErrorMsg(ErrorType, 'No Typedef for %s' % Result[0], FileTable, Result[3]) + continue + +def CheckDeclStructTypedef(FullFileName): + CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_STRUCTURE) + +def CheckDeclEnumTypedef(FullFileName): + CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_ENUMERATE) + +def CheckDeclUnionTypedef(FullFileName): + CheckDeclTypedefFormat(FullFileName, DataClass.MODEL_IDENTIFIER_UNION) + +def CheckDeclArgModifier(FullFileName): + ErrorMsgList = [] + + FileID = GetTableID(FullFileName, ErrorMsgList) + if FileID < 0: + return ErrorMsgList + + Db = GetDB() + FileTable = 'Identifier' + str(FileID) + SqlStatement = """ select Modifier, Name, ID + from %s + where Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE) + ResultSet = Db.TblFile.Exec(SqlStatement) + ModifierTuple = ('IN', 'OUT', 'OPTIONAL', 'UNALIGNED') + MAX_MODIFIER_LENGTH = 100 + for Result in ResultSet: + for Modifier in ModifierTuple: + if PatternInModifier(Result[0], Modifier) and len(Result[0]) < MAX_MODIFIER_LENGTH: + PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Variable Modifier %s' % Result[0], FileTable, Result[2]) + break + + SqlStatement = """ select Modifier, Name, ID + from %s + where Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION) + ResultSet = Db.TblFile.Exec(SqlStatement) + for Result in ResultSet: + for Modifier in ModifierTuple: + if PatternInModifier(Result[0], Modifier): + PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Return Type Modifier %s' % Result[0], FileTable, Result[2]) + break + + SqlStatement = """ select Modifier, Header, ID + from Function + where BelongsToFile = %d + """ % (FileID) + ResultSet = Db.TblFile.Exec(SqlStatement) + for Result in ResultSet: + for Modifier in ModifierTuple: + if PatternInModifier(Result[0], Modifier): + PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_IN_OUT_MODIFIER, 'Return Type Modifier %s' % Result[0], FileTable, Result[2]) + break + +def CheckDeclNoUseCType(FullFileName): + ErrorMsgList = [] + + FileID = GetTableID(FullFileName, ErrorMsgList) + if FileID < 0: + return ErrorMsgList + + Db = GetDB() + FileTable = 'Identifier' + str(FileID) + SqlStatement = """ select Modifier, Name, ID + from %s + where Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE) + ResultSet = Db.TblFile.Exec(SqlStatement) + CTypeTuple = ('int', 'unsigned', 'char', 'void', 'static', 'long') + for Result in ResultSet: + for Type in CTypeTuple: + if PatternInModifier(Result[0], Type): + PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Variable type %s' % Type, FileTable, Result[2]) + break + + SqlStatement = """ select Modifier, Name, ID, Value + from %s + where Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION) + ResultSet = Db.TblFile.Exec(SqlStatement) + for Result in ResultSet: + ParamList = GetParamList(Result[1]) + FuncName = Result[3] + if EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, FuncName): + continue + for Type in CTypeTuple: + if PatternInModifier(Result[0], Type): + PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, '%s Return type %s' % (FuncName, Result[0]), FileTable, Result[2]) + + for Param in ParamList: + if PatternInModifier(Param.Modifier, Type): + PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Parameter %s' % Param.Name, FileTable, Result[2]) + + SqlStatement = """ select Modifier, Header, ID, Name + from Function + where BelongsToFile = %d + """ % (FileID) + ResultSet = Db.TblFile.Exec(SqlStatement) + for Result in ResultSet: + ParamList = GetParamList(Result[1]) + FuncName = Result[3] + if EccGlobalData.gException.IsException(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, FuncName): + continue + for Type in CTypeTuple: + if PatternInModifier(Result[0], Type): + PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, '[%s] Return type %s' % (FuncName, Result[0]), FileTable, Result[2]) + + for Param in ParamList: + if PatternInModifier(Param.Modifier, Type): + PrintErrorMsg(ERROR_DECLARATION_DATA_TYPE_CHECK_NO_USE_C_TYPE, 'Parameter %s' % Param.Name, FileTable, Result[2]) + + +def CheckPointerNullComparison(FullFileName): + ErrorMsgList = [] + + FileID = GetTableID(FullFileName, ErrorMsgList) + if FileID < 0: + return ErrorMsgList + + # cache the found function return type to accelerate later checking in this file. + FuncReturnTypeDict = {} + + Db = GetDB() + FileTable = 'Identifier' + str(FileID) + SqlStatement = """ select Value, StartLine, ID + from %s + where Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION) + ResultSet = Db.TblFile.Exec(SqlStatement) + if len(ResultSet) == 0: + return + PSL = [] + for Result in ResultSet: + PSL.append([Result[0], Result[1], Result[2]]) + + SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID + from Function + where BelongsToFile = %d + """ % (FileID) + ResultSet = Db.TblFile.Exec(SqlStatement) + FL = [] + for Result in ResultSet: + FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]]) + + p = GetFuncDeclPattern() + for Str in PSL: + FuncRecord = GetFuncContainsPE(Str[1], FL) + if FuncRecord == None: + continue + + for Exp in GetPredicateListFromPredicateExpStr(Str[0]): + PredInfo = SplitPredicateStr(Exp) + if PredInfo[1] == None: + PredVarStr = PredInfo[0][0].strip() + IsFuncCall = False + SearchInCache = False + # PredVarStr may contain '.' or '->' + TmpStr = PredVarStr.replace('.', '').replace('->', '') + if p.match(TmpStr): + PredVarStr = PredVarStr[0:PredVarStr.find('(')] + SearchInCache = True + # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable. + if TmpStr.startswith(PredVarStr): + IsFuncCall = True + + if PredVarStr.strip() in IgnoredKeywordList: + continue + StarList = [] + PredVarList = GetCNameList(PredVarStr, StarList) + # No variable found, maybe value first? like (0 == VarName) + if len(PredVarList) == 0: + continue + if SearchInCache: + Type = FuncReturnTypeDict.get(PredVarStr) + if Type != None: + if Type.find('*') != -1: + PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Predicate Expression: %s' % Exp, FileTable, Str[2]) + continue + + if PredVarStr in FuncReturnTypeDict: + continue + + Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, None, StarList) + if SearchInCache: + FuncReturnTypeDict[PredVarStr] = Type + if Type == None: + continue + if Type.find('*') != -1: + PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_COMPARISON_NULL_TYPE, 'Predicate Expression: %s' % Exp, FileTable, Str[2]) + +def CheckNonBooleanValueComparison(FullFileName): + ErrorMsgList = [] + + FileID = GetTableID(FullFileName, ErrorMsgList) + if FileID < 0: + return ErrorMsgList + + # cache the found function return type to accelerate later checking in this file. + FuncReturnTypeDict = {} + + Db = GetDB() + FileTable = 'Identifier' + str(FileID) + SqlStatement = """ select Value, StartLine, ID + from %s + where Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION) + ResultSet = Db.TblFile.Exec(SqlStatement) + if len(ResultSet) == 0: + return + PSL = [] + for Result in ResultSet: + PSL.append([Result[0], Result[1], Result[2]]) + + SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID + from Function + where BelongsToFile = %d + """ % (FileID) + ResultSet = Db.TblFile.Exec(SqlStatement) + FL = [] + for Result in ResultSet: + FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]]) + + p = GetFuncDeclPattern() + for Str in PSL: + FuncRecord = GetFuncContainsPE(Str[1], FL) + if FuncRecord == None: + continue + + for Exp in GetPredicateListFromPredicateExpStr(Str[0]): +# if p.match(Exp): +# continue + PredInfo = SplitPredicateStr(Exp) + if PredInfo[1] == None: + PredVarStr = PredInfo[0][0].strip() + IsFuncCall = False + SearchInCache = False + # PredVarStr may contain '.' or '->' + TmpStr = PredVarStr.replace('.', '').replace('->', '') + if p.match(TmpStr): + PredVarStr = PredVarStr[0:PredVarStr.find('(')] + SearchInCache = True + # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable. + if TmpStr.startswith(PredVarStr): + IsFuncCall = True + + if PredVarStr.strip() in IgnoredKeywordList: + continue + StarList = [] + PredVarList = GetCNameList(PredVarStr, StarList) + # No variable found, maybe value first? like (0 == VarName) + if len(PredVarList) == 0: + continue + + if SearchInCache: + Type = FuncReturnTypeDict.get(PredVarStr) + if Type != None: + if Type.find('BOOLEAN') == -1: + PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Predicate Expression: %s' % Exp, FileTable, Str[2]) + continue + + if PredVarStr in FuncReturnTypeDict: + continue + + Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, 'BOOLEAN', StarList) + if SearchInCache: + FuncReturnTypeDict[PredVarStr] = Type + if Type == None: + continue + if Type.find('BOOLEAN') == -1: + PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_NO_BOOLEAN_OPERATOR, 'Predicate Expression: %s' % Exp, FileTable, Str[2]) + + +def CheckBooleanValueComparison(FullFileName): + ErrorMsgList = [] + + FileID = GetTableID(FullFileName, ErrorMsgList) + if FileID < 0: + return ErrorMsgList + + # cache the found function return type to accelerate later checking in this file. + FuncReturnTypeDict = {} + + Db = GetDB() + FileTable = 'Identifier' + str(FileID) + SqlStatement = """ select Value, StartLine, ID + from %s + where Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_PREDICATE_EXPRESSION) + ResultSet = Db.TblFile.Exec(SqlStatement) + if len(ResultSet) == 0: + return + PSL = [] + for Result in ResultSet: + PSL.append([Result[0], Result[1], Result[2]]) + + SqlStatement = """ select BodyStartLine, EndLine, Header, Modifier, ID + from Function + where BelongsToFile = %d + """ % (FileID) + ResultSet = Db.TblFile.Exec(SqlStatement) + FL = [] + for Result in ResultSet: + FL.append([Result[0], Result[1], Result[2], Result[3], Result[4]]) + + p = GetFuncDeclPattern() + for Str in PSL: + FuncRecord = GetFuncContainsPE(Str[1], FL) + if FuncRecord == None: + continue + + for Exp in GetPredicateListFromPredicateExpStr(Str[0]): + PredInfo = SplitPredicateStr(Exp) + if PredInfo[1] in ('==', '!=') and PredInfo[0][1] in ('TRUE', 'FALSE'): + PredVarStr = PredInfo[0][0].strip() + IsFuncCall = False + SearchInCache = False + # PredVarStr may contain '.' or '->' + TmpStr = PredVarStr.replace('.', '').replace('->', '') + if p.match(TmpStr): + PredVarStr = PredVarStr[0:PredVarStr.find('(')] + SearchInCache = True + # Only direct function call using IsFuncCall branch. Multi-level ref. function call is considered a variable. + if TmpStr.startswith(PredVarStr): + IsFuncCall = True + + if PredVarStr.strip() in IgnoredKeywordList: + continue + StarList = [] + PredVarList = GetCNameList(PredVarStr, StarList) + # No variable found, maybe value first? like (0 == VarName) + if len(PredVarList) == 0: + continue + + if SearchInCache: + Type = FuncReturnTypeDict.get(PredVarStr) + if Type != None: + if Type.find('BOOLEAN') != -1: + PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Predicate Expression: %s' % Exp, FileTable, Str[2]) + continue + + if PredVarStr in FuncReturnTypeDict: + continue + + Type = GetVarInfo(PredVarList, FuncRecord, FullFileName, IsFuncCall, 'BOOLEAN', StarList) + if SearchInCache: + FuncReturnTypeDict[PredVarStr] = Type + if Type == None: + continue + if Type.find('BOOLEAN') != -1: + PrintErrorMsg(ERROR_PREDICATE_EXPRESSION_CHECK_BOOLEAN_VALUE, 'Predicate Expression: %s' % Exp, FileTable, Str[2]) + + +def CheckHeaderFileData(FullFileName): + ErrorMsgList = [] + + FileID = GetTableID(FullFileName, ErrorMsgList) + if FileID < 0: + return ErrorMsgList + + Db = GetDB() + FileTable = 'Identifier' + str(FileID) + SqlStatement = """ select ID, Modifier + from %s + where Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_VARIABLE) + ResultSet = Db.TblFile.Exec(SqlStatement) + for Result in ResultSet: + if not Result[1].startswith('extern'): + PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_DATA, 'Variable definition appears in header file', FileTable, Result[0]) + + SqlStatement = """ select ID + from Function + where BelongsToFile = %d + """ % FileID + ResultSet = Db.TblFile.Exec(SqlStatement) + for Result in ResultSet: + PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_DATA, 'Function definition appears in header file', 'Function', Result[0]) + + return ErrorMsgList + +def CheckHeaderFileIfndef(FullFileName): + ErrorMsgList = [] + + FileID = GetTableID(FullFileName, ErrorMsgList) + if FileID < 0: + return ErrorMsgList + + Db = GetDB() + FileTable = 'Identifier' + str(FileID) + SqlStatement = """ select Value, StartLine + from %s + where Model = %d order by StartLine + """ % (FileTable, DataClass.MODEL_IDENTIFIER_MACRO_IFNDEF) + ResultSet = Db.TblFile.Exec(SqlStatement) + if len(ResultSet) == 0: + PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_1, '', 'File', FileID) + return ErrorMsgList + for Result in ResultSet: + SqlStatement = """ select Value, EndLine + from %s + where EndLine < %d + """ % (FileTable, Result[1]) + ResultSet = Db.TblFile.Exec(SqlStatement) + for Result in ResultSet: + if not Result[0].startswith('/*') and not Result[0].startswith('//'): + PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_2, '', 'File', FileID) + break + + SqlStatement = """ select Value + from %s + where StartLine > (select max(EndLine) from %s where Model = %d) + """ % (FileTable, FileTable, DataClass.MODEL_IDENTIFIER_MACRO_ENDIF) + ResultSet = Db.TblFile.Exec(SqlStatement) + for Result in ResultSet: + if not Result[0].startswith('/*') and not Result[0].startswith('//'): + PrintErrorMsg(ERROR_INCLUDE_FILE_CHECK_IFNDEF_STATEMENT_3, '', 'File', FileID) + return ErrorMsgList + +def CheckDoxygenCommand(FullFileName): + ErrorMsgList = [] + + FileID = GetTableID(FullFileName, ErrorMsgList) + if FileID < 0: + return ErrorMsgList + + Db = GetDB() + FileTable = 'Identifier' + str(FileID) + SqlStatement = """ select Value, ID + from %s + where Model = %d or Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER) + ResultSet = Db.TblFile.Exec(SqlStatement) + DoxygenCommandList = ['bug', 'todo', 'example', 'file', 'attention', 'param', 'post', 'pre', 'retval', 'return', 'sa', 'since', 'test', 'note', 'par'] + for Result in ResultSet: + CommentStr = Result[0] + CommentPartList = CommentStr.split() + for Part in CommentPartList: + if Part.upper() == 'BUGBUG': + PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Bug should be marked with doxygen tag @bug', FileTable, Result[1]) + if Part.upper() == 'TODO': + PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'ToDo should be marked with doxygen tag @todo', FileTable, Result[1]) + if Part.startswith('@'): + if EccGlobalData.gException.IsException(ERROR_DOXYGEN_CHECK_COMMAND, Part): + continue + if Part.lstrip('@').isalpha(): + if Part.lstrip('@') not in DoxygenCommandList: + PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1]) + else: + Index = Part.find('[') + if Index == -1: + PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1]) + RealCmd = Part[1:Index] + if RealCmd not in DoxygenCommandList: + PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMAND, 'Unknown doxygen command %s' % Part, FileTable, Result[1]) + + +def CheckDoxygenTripleForwardSlash(FullFileName): + ErrorMsgList = [] + + FileID = GetTableID(FullFileName, ErrorMsgList) + if FileID < 0: + return ErrorMsgList + + Db = GetDB() + + SqlStatement = """ select ID, BodyStartLine, BodyStartColumn, EndLine, EndColumn + from Function + where BelongsToFile = %d + """ % (FileID) + ResultSet = Db.TblFile.Exec(SqlStatement) + if len(ResultSet) == 0: + return + + FuncDefSet = [] + for Result in ResultSet: + FuncDefSet.append(Result) + + + FileTable = 'Identifier' + str(FileID) + SqlStatement = """ select Value, ID, StartLine, StartColumn, EndLine, EndColumn + from %s + where Model = %d + + """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT) + ResultSet = Db.TblFile.Exec(SqlStatement) + CommentSet = [] + try: + for Result in ResultSet: + CommentSet.append(Result) + except: + print 'Unrecognized chars in comment of file %s', FullFileName + + + for Result in CommentSet: + CommentStr = Result[0] + StartLine = Result[2] + StartColumn = Result[3] + EndLine = Result[4] + EndColumn = Result[5] + if not CommentStr.startswith('///<'): + continue + + Found = False + for FuncDef in FuncDefSet: + if StartLine == FuncDef[1] and StartColumn > FuncDef[2] and EndLine == FuncDef[3] and EndColumn < FuncDef[4]: + Found = True + break + if StartLine > FuncDef[1] and EndLine < FuncDef[3]: + Found = True + break + if StartLine == FuncDef[1] and StartColumn > FuncDef[2] and EndLine < FuncDef[3]: + Found = True + break + if StartLine > FuncDef[1] and EndLine == FuncDef[3] and EndColumn < FuncDef[4]: + Found = True + break + if Found: + PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_FORMAT, '', FileTable, Result[1]) + + +def CheckFileHeaderDoxygenComments(FullFileName): + ErrorMsgList = [] + + FileID = GetTableID(FullFileName, ErrorMsgList) + if FileID < 0: + return ErrorMsgList + + Db = GetDB() + FileTable = 'Identifier' + str(FileID) + SqlStatement = """ select Value, ID + from %s + where Model = %d and StartLine = 1 and StartColumn = 0 + """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT) + ResultSet = Db.TblFile.Exec(SqlStatement) + if len(ResultSet) == 0: + PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'No Comment appear at the very beginning of file.', 'File', FileID) + return ErrorMsgList + + for Result in ResultSet: + CommentStr = Result[0] + if not CommentStr.startswith('/** @file'): + PrintErrorMsg(ERROR_DOXYGEN_CHECK_FILE_HEADER, 'File header comment should begin with ""/** @file""', FileTable, Result[1]) + if not CommentStr.endswith('**/'): + PrintErrorMsg(ERROR_HEADER_CHECK_FILE, 'File header comment should end with **/', FileTable, Result[1]) + if CommentStr.find('.') == -1: + PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION, 'Comment description should end with period \'.\'', FileTable, Result[1]) + +def CheckFuncHeaderDoxygenComments(FullFileName): + ErrorMsgList = [] + + FileID = GetTableID(FullFileName, ErrorMsgList) + if FileID < 0: + return ErrorMsgList + + Db = GetDB() + FileTable = 'Identifier' + str(FileID) + SqlStatement = """ select Value, StartLine, EndLine, ID + from %s + where Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_COMMENT) + + ResultSet = Db.TblFile.Exec(SqlStatement) + CommentSet = [] + try: + for Result in ResultSet: + CommentSet.append(Result) + except: + print 'Unrecognized chars in comment of file %s', FullFileName + + # Func Decl check + SqlStatement = """ select Modifier, Name, StartLine, ID, Value + from %s + where Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_DECLARATION) + ResultSet = Db.TblFile.Exec(SqlStatement) + for Result in ResultSet: + FuncName = Result[4] + FunctionHeaderComment = CheckCommentImmediatelyPrecedeFunctionHeader(Result[1], Result[2], CommentSet) + if FunctionHeaderComment: + CheckFunctionHeaderConsistentWithDoxygenComment(Result[0], Result[1], Result[2], FunctionHeaderComment[0], FunctionHeaderComment[1], ErrorMsgList, FunctionHeaderComment[3], FileTable) + else: + if EccGlobalData.gException.IsException(ERROR_HEADER_CHECK_FUNCTION, FuncName): + continue + ErrorMsgList.append('Line %d :Function %s has NO comment immediately preceding it.' % (Result[2], Result[1])) + PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'Function [%s] has NO comment immediately preceding it.' % (FuncName), FileTable, Result[3]) + + # Func Def check + SqlStatement = """ select Value, StartLine, EndLine, ID + from %s + where Model = %d + """ % (FileTable, DataClass.MODEL_IDENTIFIER_FUNCTION_HEADER) + + ResultSet = Db.TblFile.Exec(SqlStatement) + CommentSet = [] + try: + for Result in ResultSet: + CommentSet.append(Result) + except: + print 'Unrecognized chars in comment of file %s', FullFileName + + SqlStatement = """ select Modifier, Header, StartLine, ID, Name + from Function + where BelongsToFile = %d + """ % (FileID) + ResultSet = Db.TblFile.Exec(SqlStatement) + for Result in ResultSet: + FuncName = Result[4] + FunctionHeaderComment = CheckCommentImmediatelyPrecedeFunctionHeader(Result[1], Result[2], CommentSet) + if FunctionHeaderComment: + CheckFunctionHeaderConsistentWithDoxygenComment(Result[0], Result[1], Result[2], FunctionHeaderComment[0], FunctionHeaderComment[1], ErrorMsgList, FunctionHeaderComment[3], FileTable) + else: + if EccGlobalData.gException.IsException(ERROR_HEADER_CHECK_FUNCTION, FuncName): + continue + ErrorMsgList.append('Line %d :Function [%s] has NO comment immediately preceding it.' % (Result[2], Result[1])) + PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'Function [%s] has NO comment immediately preceding it.' % (FuncName), 'Function', Result[3]) + return ErrorMsgList + +def CheckCommentImmediatelyPrecedeFunctionHeader(FuncName, FuncStartLine, CommentSet): + + for Comment in CommentSet: + if Comment[2] == FuncStartLine - 1: + return Comment + return None + +def GetDoxygenStrFromComment(Str): + DoxygenStrList = [] + ParamTagList = Str.split('@param') + if len(ParamTagList) > 1: + i = 1 + while i < len(ParamTagList): + DoxygenStrList.append('@param' + ParamTagList[i]) + i += 1 + + Str = ParamTagList[0] + + RetvalTagList = ParamTagList[-1].split('@retval') + if len(RetvalTagList) > 1: + if len(ParamTagList) > 1: + DoxygenStrList[-1] = '@param' + RetvalTagList[0] + i = 1 + while i < len(RetvalTagList): + DoxygenStrList.append('@retval' + RetvalTagList[i]) + i += 1 + + ReturnTagList = RetvalTagList[-1].split('@return') + if len(ReturnTagList) > 1: + if len(RetvalTagList) > 1: + DoxygenStrList[-1] = '@retval' + ReturnTagList[0] + elif len(ParamTagList) > 1: + DoxygenStrList[-1] = '@param' + ReturnTagList[0] + i = 1 + while i < len(ReturnTagList): + DoxygenStrList.append('@return' + ReturnTagList[i]) + i += 1 + + if len(DoxygenStrList) > 0: + DoxygenStrList[-1] = DoxygenStrList[-1].rstrip('--*/') + + return DoxygenStrList + +def CheckGeneralDoxygenCommentLayout(Str, StartLine, ErrorMsgList, CommentId = -1, TableName = ''): + #/** --*/ @retval after @param + if not Str.startswith('/**'): + ErrorMsgList.append('Line %d : Comment does NOT have prefix /** ' % StartLine) + PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Comment does NOT have prefix /** ', TableName, CommentId) + if not Str.endswith('**/'): + ErrorMsgList.append('Line %d : Comment does NOT have tail **/ ' % StartLine) + PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Comment does NOT have tail **/ ', TableName, CommentId) + FirstRetvalIndex = Str.find('@retval') + LastParamIndex = Str.rfind('@param') + if (FirstRetvalIndex > 0) and (LastParamIndex > 0) and (FirstRetvalIndex < LastParamIndex): + ErrorMsgList.append('Line %d : @retval appear before @param ' % StartLine) + PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, @retval appear before @param ', TableName, CommentId) + +def CheckFunctionHeaderConsistentWithDoxygenComment(FuncModifier, FuncHeader, FuncStartLine, CommentStr, CommentStartLine, ErrorMsgList, CommentId = -1, TableName = ''): + + ParamList = GetParamList(FuncHeader) + CheckGeneralDoxygenCommentLayout(CommentStr, CommentStartLine, ErrorMsgList, CommentId, TableName) + DescriptionStr = CommentStr + DoxygenStrList = GetDoxygenStrFromComment(DescriptionStr) + if DescriptionStr.find('.') == -1: + PrintErrorMsg(ERROR_DOXYGEN_CHECK_COMMENT_DESCRIPTION, 'Comment description should end with period \'.\'', TableName, CommentId) + DoxygenTagNumber = len(DoxygenStrList) + ParamNumber = len(ParamList) + for Param in ParamList: + if Param.Name.upper() == 'VOID' and ParamNumber == 1: + ParamNumber -= 1 + Index = 0 + if ParamNumber > 0 and DoxygenTagNumber > 0: + while Index < ParamNumber and Index < DoxygenTagNumber: + ParamModifier = ParamList[Index].Modifier + ParamName = ParamList[Index].Name.strip() + Tag = DoxygenStrList[Index].strip(' ') + if (not Tag[-1] == ('\n')) and (not Tag[-1] == ('\r')): + ErrorMsgList.append('Line %d : in Comment, \"%s\" does NOT end with new line ' % (CommentStartLine, Tag.replace('\n', '').replace('\r', ''))) + PrintErrorMsg(ERROR_HEADER_CHECK_FUNCTION, 'in Comment, \"%s\" does NOT end with new line ' % (Tag.replace('\n', '').replace('\r', '')), TableName, CommentId) + TagPartList = Tag.split() + if len(TagPartList) < 2: + ErrorMsgList.append('Line %d : in Comment, \"%s\" does NOT contain doxygen contents ' % (CommentStartLine, Tag.replace('\n', '').replace('\r', ''))) + PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, \"%s\" does NOT contain doxygen contents ' % (Tag.replace('\n', '').replace('\r', '')), TableName, CommentId) + Index += 1 + continue + LBPos = Tag.find('[') + RBPos = Tag.find(']') + ParamToLBContent = Tag[len('@param'):LBPos].strip() + if LBPos > 0 and len(ParamToLBContent)==0 and RBPos > LBPos: + InOutStr = '' + ModifierPartList = ParamModifier.split() + for Part in ModifierPartList: + if Part.strip() == 'IN': + InOutStr += 'in' + if Part.strip() == 'OUT': + if InOutStr != '': + InOutStr += ', out' + else: + InOutStr = 'out' + + if InOutStr != '': + if Tag.find('['+InOutStr+']') == -1: + ErrorMsgList.append('Line %d : in Comment, \"%s\" does NOT have %s ' % (CommentStartLine, (TagPartList[0] + ' ' +TagPartList[1]).replace('\n', '').replace('\r', ''), '['+InOutStr+']')) + PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, \"%s\" does NOT have %s ' % ((TagPartList[0] + ' ' +TagPartList[1]).replace('\n', '').replace('\r', ''), '['+InOutStr+']'), TableName, CommentId) + if Tag.find(ParamName) == -1 and ParamName != 'VOID' and ParamName != 'void': + ErrorMsgList.append('Line %d : in Comment, \"%s\" does NOT consistent with parameter name %s ' % (CommentStartLine, (TagPartList[0] + ' ' +TagPartList[1]).replace('\n', '').replace('\r', ''), ParamName)) + PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'in Comment, \"%s\" does NOT consistent with parameter name %s ' % ((TagPartList[0] + ' ' +TagPartList[1]).replace('\n', '').replace('\r', ''), ParamName), TableName, CommentId) + Index += 1 + + if Index < ParamNumber: + ErrorMsgList.append('Line %d : Number of doxygen tags in comment less than number of function parameters' % CommentStartLine) + PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Number of doxygen tags in comment less than number of function parameters ', TableName, CommentId) + # VOID return type, NOT VOID*. VOID* should be matched with a doxygen tag. + if (FuncModifier.find('VOID') != -1 or FuncModifier.find('void') != -1) and FuncModifier.find('*') == -1: + + # assume we allow a return description tag for void func. return. that's why 'DoxygenTagNumber - 1' is used instead of 'DoxygenTagNumber' + if Index < DoxygenTagNumber - 1 or (Index < DoxygenTagNumber and DoxygenStrList[Index].startswith('@retval')): + ErrorMsgList.append('Line %d : VOID return type need NO doxygen tags in comment' % CommentStartLine) + PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'VOID return type need no doxygen tags in comment ', TableName, CommentId) + else: + if Index < DoxygenTagNumber and not DoxygenStrList[Index].startswith('@retval') and not DoxygenStrList[Index].startswith('@return'): + ErrorMsgList.append('Line %d : Number of @param doxygen tags in comment does NOT match number of function parameters' % CommentStartLine) + PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'Number of @param doxygen tags in comment does NOT match number of function parameters ', TableName, CommentId) + else: + if ParamNumber == 0 and DoxygenTagNumber != 0 and ((FuncModifier.find('VOID') != -1 or FuncModifier.find('void') != -1) and FuncModifier.find('*') == -1): + ErrorMsgList.append('Line %d : VOID return type need NO doxygen tags in comment' % CommentStartLine) + PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'VOID return type need NO doxygen tags in comment ', TableName, CommentId) + if ParamNumber != 0 and DoxygenTagNumber == 0: + ErrorMsgList.append('Line %d : No doxygen tags in comment' % CommentStartLine) + PrintErrorMsg(ERROR_DOXYGEN_CHECK_FUNCTION_HEADER, 'No doxygen tags in comment ', TableName, CommentId) + +if __name__ == '__main__': + +# EdkLogger.Initialize() +# EdkLogger.SetLevel(EdkLogger.QUIET) +# CollectSourceCodeDataIntoDB(sys.argv[1]) + MsgList = CheckFuncHeaderDoxygenComments('C:\\Combo\\R9\\LakeportX64Dev\\FlashDevicePkg\\Library\\SpiFlashChipM25P64\\SpiFlashChipM25P64.c') + for Msg in MsgList: + print Msg + print 'Done!' diff --git a/BaseTools/Source/Python/Ecc/config.ini b/BaseTools/Source/Python/Ecc/config.ini new file mode 100644 index 0000000000..a3215aedaa --- /dev/null +++ b/BaseTools/Source/Python/Ecc/config.ini @@ -0,0 +1,242 @@ +## @file +# This file is used to set configuration of ECC tool +# For the items listed below, 1 means valid, 0 means invalid +# +# Copyright (c) 2007, 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 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. +# + +# +# Identify the version of current configuration +# +Version = 0.1 + +# +# Identify to if check all items +# 1 - Check all items and ignore all other detailed items +# 0 - Not check all items, the tool will go through all other detailed items to decide to check or not +# +CheckAll = 0 + +# +# Identify to if automatically correct mistakes +# 1 - Automatically correct +# 0 - Not automatically correct +# Only the following check points can be automatically corrected, others not listed below are not supported even it is 1 +# +# GeneralCheckTab +# GeneralCheckIndentation +# GeneralCheckLine +# GeneralCheckCarriageReturn +# SpaceCheckAll +# +AutoCorrect = 1 + +# +# List customized Modifer here, split with ',' +# +ModifierList = IN, OUT, OPTIONAL, UNALIGNED, EFI_RUNTIMESERVICE, EFI_BOOTSERVICE, EFIAPI, TPMINTERNALAPI + +# +# General Checking +# +GeneralCheckAll = 0 + +# Check whether NO Tab is used, replaced with spaces +GeneralCheckNoTab = 1 +# The width of Tab +GeneralCheckTabWidth = 2 +# Check whether the indentation is followed coding style +GeneralCheckIndentation = 1 +# The width of indentation +GeneralCheckIndentationWidth = 2 +# Check whether no line is exceeding defined widty +GeneralCheckLine = 1 +# The width of a line +GeneralCheckLineWidth = 120 +# Check whether no use of _asm in the source file +GeneralCheckNo_Asm = 1 +# Check whether no use of "#progma" in source file except "#pragma pack(#)". +GeneralCheckNoProgma = 1 +# Check whether there is a carriage return at the end of the file +GeneralCheckCarriageReturn = 1 +# Check whether the file exists +GeneralCheckFileExistence = 1 + +# +# Space Checking +# +SpaceCheckAll = 1 + +# +# Predicate Expression Checking +# +PredicateExpressionCheckAll = 0 + +# Check whether Boolean values, variable type BOOLEAN not use explicit comparisons to TRUE or FALSE +PredicateExpressionCheckBooleanValue = 1 +# Check whether Non-Boolean comparisons use a compare operator (==, !=, >, < >=, <=). +PredicateExpressionCheckNonBooleanOperator = 1 +# Check whether a comparison of any pointer to zero must be done via the NULL type +PredicateExpressionCheckComparisonNullType = 1 + +# +# Headers Checking +# +HeaderCheckAll = 0 + +# Check whether File header exists +HeaderCheckFile = 1 +# Check whether Function header exists +HeaderCheckFunction = 1 + +# +# C Function Layout Checking +# +CFunctionLayoutCheckAll = 0 + +# Check whether return type exists and in the first line +CFunctionLayoutCheckReturnType = 1 +# Check whether any optional functional modifiers exist and next to the return type +CFunctionLayoutCheckOptionalFunctionalModifier = 1 +# Check whether the next line contains the function name, left justified, followed by the beginning of the parameter list +# Check whether the closing parenthesis is on its own line and also indented two spaces +CFunctionLayoutCheckFunctionName = 1 +# Check whether the function prototypes in include files have the same form as function definitions +CFunctionLayoutCheckFunctionPrototype = 1 +# Check whether the body of a function is contained by open and close braces that must be in the first column +CFunctionLayoutCheckFunctionBody = 1 +# Check whether the data declarations is the first code in a module. +CFunctionLayoutCheckDataDeclaration = 1 +# Check whether no initialization of a variable as part of its declaration +CFunctionLayoutCheckNoInitOfVariable = 1 +# Check whether no use of STATIC for functions +CFunctionLayoutCheckNoStatic = 1 + +# +# Include Files Checking +# +IncludeFileCheckAll = 0 + +#Check whether having include files with same name +IncludeFileCheckSameName = 1 +# Check whether all include file contents is guarded by a #ifndef statement. +# the #ifndef must be the first line of code following the file header comment +# the #endif must appear on the last line in the file +IncludeFileCheckIfndefStatement = 1 +# Check whether include files contain only public or only private data +# Check whether include files NOT contain code or define data variables +IncludeFileCheckData = 1 + +# +# Declarations and Data Types Checking +# +DeclarationDataTypeCheckAll = 0 + +# Check whether no use of int, unsigned, char, void, static, long in any .c, .h or .asl files. +DeclarationDataTypeCheckNoUseCType = 1 +# Check whether the modifiers IN, OUT, OPTIONAL, and UNALIGNED are used only to qualify arguments to a function and should not appear in a data type declaration +DeclarationDataTypeCheckInOutModifier = 1 +# Check whether the EFIAPI modifier should be used at the entry of drivers, events, and member functions of protocols +DeclarationDataTypeCheckEFIAPIModifier = 1 +# Check whether Enumerated Type has a 'typedef' and the name is capital +DeclarationDataTypeCheckEnumeratedType = 1 +# Check whether Structure Type has a 'typedef' and the name is capital +DeclarationDataTypeCheckStructureDeclaration = 1 +# Check whether having same Structure +DeclarationDataTypeCheckSameStructure = 1 +# Check whether Union Type has a 'typedef' and the name is capital +DeclarationDataTypeCheckUnionType = 1 + + +# +# Naming Conventions Checking +# +NamingConventionCheckAll = 0 + +# Check whether only capital letters are used for #define declarations +NamingConventionCheckDefineStatement = 1 +# Check whether only capital letters are used for typedef declarations +NamingConventionCheckTypedefStatement = 1 +# Check whether the #ifndef at the start of an include file uses both prefix and postfix underscore characters, '_'. +NamingConventionCheckIfndefStatement = 1 +# Rule for path name, variable name and function name +# 1. First character should be upper case +# 2. Existing lower case in a word +# 3. No space existence +# 4. Global variable name must start by a 'g' +# Check whether the path name followed the rule +NamingConventionCheckPathName = 1 +# Check whether the variable name followed the rule +NamingConventionCheckVariableName = 1 +# Check whether the function name followed the rule +NamingConventionCheckFunctionName = 1 +# Check whether NO use short variable name with single character +NamingConventionCheckSingleCharacterVariable = 1 + +# +# Doxygen Checking +# +DoxygenCheckAll = 0 + +# Check whether the file headers are followed Doxygen special documentation blocks in section 2.3.5 +DoxygenCheckFileHeader = 1 +# Check whether the function headers are followed Doxygen special documentation blocks in section 2.3.5 +DoxygenCheckFunctionHeader = 1 +# Check whether the first line of text in a comment block is a brief description of the element being documented. +# The brief description must end with a period. +DoxygenCheckCommentDescription = 1 +# Check whether comment lines with '///< ... text ...' format, if it is used, it should be after the code section. +DoxygenCheckCommentFormat = 1 +# Check whether only Doxygen commands allowed to mark the code are @bug and @todo. +DoxygenCheckCommand = 1 + +# +# Meta-Data File Processing Checking +# +MetaDataFileCheckAll = 0 + +# Check whether each file defined in meta-data exists +MetaDataFileCheckPathName = 1 +# Generate a list for all files defined in meta-data files +MetaDataFileCheckGenerateFileList = 1 +# The path of log file +MetaDataFileCheckPathOfGenerateFileList = File.log +# Check whether all Library Instances defined for a given module (or dependent library instance) match the module's type. +# Each Library Instance must specify the Supported Module Types in its INF file, +# and any module specifying the library instance must be one of the supported types. +MetaDataFileCheckLibraryInstance = 1 +# Check whether a Library Instance has been defined for all dependent library classes +MetaDataFileCheckLibraryInstanceDependent = 1 +# Check whether the Library Instances specified by the LibraryClasses sections are listed in order of dependencies +MetaDataFileCheckLibraryInstanceOrder = 1 +# Check whether the unnecessary inclusion of library classes in the INF file +MetaDataFileCheckLibraryNoUse = 1 +# Check whether an INF file is specified in the FDF file, but not in the DSC file, then the INF file must be for a Binary module only +MetaDataFileCheckBinaryInfInFdf = 1 +# Not to report error and warning related OS include file such as "windows.h" and "stdio.h". +# Check whether a PCD is set in a DSC file or the FDF file, but not in both. +MetaDataFileCheckPcdDuplicate = 1 +# Check whether PCD settings in the FDF file can only be related to flash. +MetaDataFileCheckPcdFlash = 1 +# Check whether PCDs used in INF files but not specified in DSC or FDF files +MetaDataFileCheckPcdNoUse = 1 +# Check whether having duplicate guids defined for Guid/Protocol/Ppi +MetaDataFileCheckGuidDuplicate = 1 +# Check whether all files under module directory are described in INF files +MetaDataFileCheckModuleFileNoUse = 1 +# Check whether the PCD is correctly used in C function via its type +MetaDataFileCheckPcdType = 1 + +# +# The check points in this section are reserved +# +# GotoStatementCheckAll = 0 +# SpellingCheckAll = 0 +# diff --git a/BaseTools/Source/Python/Ecc/exception.xml b/BaseTools/Source/Python/Ecc/exception.xml new file mode 100644 index 0000000000..0dc67527b5 --- /dev/null +++ b/BaseTools/Source/Python/Ecc/exception.xml @@ -0,0 +1,310 @@ + + + __debugbreak + 4002 + + + __readmsr + 4002 + + + __writemsr + 4002 + + + _InterlockedCompareExchange + 4002 + + + _InterlockedCompareExchange64 + 4002 + + + _InterlockedDecrement + 4002 + + + _InterlockedIncrement + 4002 + + + _break + 4002 + + + _inp + 4002 + + + _inpw + 4002 + + + _inpd + 4002 + + + _outp + 4002 + + + _outpw + 4002 + + + _outpd + 4002 + + + _ReadWriteBarrier + 4002 + + + InternalX86DisablePaging32 + 4002 + + + InternalX86EnablePaging32 + 4002 + + + InternalLongJump + 4002 + + + SetJump + 4002 + + + __debugbreak + 5001 + + + __readmsr + 5001 + + + __writemsr + 5001 + + + _InterlockedCompareExchange + 5001 + + + _InterlockedCompareExchange64 + 5001 + + + _InterlockedDecrement + 5001 + + + _InterlockedIncrement + 5001 + + + _inp + 5001 + + + _inpw + 5001 + + + _inpd + 5001 + + + _outp + 5001 + + + _outpw + 5001 + + + _outpd + 5001 + + + _ReadWriteBarrier + 5001 + + + IoRead8 + 5001 + + + IoWrite8 + 5001 + + + IoRead16 + 5001 + + + IoWrite16 + 5001 + + + IoRead32 + 5001 + + + IoWrite32 + 5001 + + + __debugbreak + 5003 + + + __readmsr + 5003 + + + __writemsr + 5003 + + + _InterlockedCompareExchange + 5003 + + + _InterlockedCompareExchange64 + 5003 + + + _InterlockedDecrement + 5003 + + + _InterlockedIncrement + 5003 + + + _inp + 5003 + + + _inpw + 5003 + + + _inpd + 5003 + + + _outp + 5003 + + + _outpw + 5003 + + + _outpd + 5003 + + + _ReadWriteBarrier + 5003 + + + __debugbreak + 7001 + + + __readmsr + 7001 + + + __writemsr + 7001 + + + _InterlockedCompareExchange + 7001 + + + _InterlockedCompareExchange64 + 7001 + + + _InterlockedDecrement + 7001 + + + _InterlockedIncrement + 7001 + + + _inp + 7001 + + + _inpw + 7001 + + + _inpd + 7001 + + + _outp + 7001 + + + _outpw + 7001 + + + _outpd + 7001 + + + _ReadWriteBarrier + 7001 + + + @ + 9005 + + + @R1 + 9005 + + + @R2 + 9005 + + + @Rx + 9005 + + + @R2. + 9005 + + + _DriverUnloadHandler + 8006 + + + ASSERT + 10015 + + + REPORT_STATUS_CODE + 10015 + + + REPORT_STATUS_CODE_WITH_EXTENDED_DATA + 10015 + + + REPORT_STATUS_CODE_WITH_DEVICE_PATH + 10015 + + \ No newline at end of file diff --git a/BaseTools/Source/Python/Fdb/__init__.py b/BaseTools/Source/Python/Fdb/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/BaseTools/Source/Python/FixFlash/__init__.py b/BaseTools/Source/Python/FixFlash/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/BaseTools/Source/Python/GNUmakefile b/BaseTools/Source/Python/GNUmakefile new file mode 100644 index 0000000000..aa569b3624 --- /dev/null +++ b/BaseTools/Source/Python/GNUmakefile @@ -0,0 +1,6 @@ + +all: + +clean: + find . -name '*.pyc' -exec rm '{}' ';' + diff --git a/BaseTools/Source/Python/GenFds/AprioriSection.py b/BaseTools/Source/Python/GenFds/AprioriSection.py new file mode 100644 index 0000000000..92a9794f51 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/AprioriSection.py @@ -0,0 +1,118 @@ +## @file +# process APRIORI file data and generate PEI/DXE APRIORI file +# +# Copyright (c) 2007, 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 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 +# +from struct import * +import os +import StringIO +import FfsFileStatement +from GenFdsGlobalVariable import GenFdsGlobalVariable +from CommonDataClass.FdfClass import AprioriSectionClassObject +from Common.String import * +from Common.Misc import SaveFileOnChange,PathClass +from Common import EdkLogger +from Common.BuildToolError import * + +## process APRIORI file data and generate PEI/DXE APRIORI file +# +# +class AprioriSection (AprioriSectionClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + AprioriSectionClassObject.__init__(self) + self.AprioriType = "" + + ## GenFfs() method + # + # Generate FFS for APRIORI file + # + # @param self The object pointer + # @param FvName for whom apriori file generated + # @param Dict dictionary contains macro and its value + # @retval string Generated file name + # + def GenFfs (self, FvName, Dict = {}): + DXE_GUID = "FC510EE7-FFDC-11D4-BD41-0080C73C8881" + PEI_GUID = "1B45CC0A-156A-428A-AF62-49864DA0E6E6" + Buffer = StringIO.StringIO('') + AprioriFileGuid = DXE_GUID + if self.AprioriType == "PEI": + AprioriFileGuid = PEI_GUID + OutputAprFilePath = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, \ + GenFdsGlobalVariable.FfsDir,\ + AprioriFileGuid + FvName) + if not os.path.exists(OutputAprFilePath) : + os.makedirs(OutputAprFilePath) + + OutputAprFileName = os.path.join( OutputAprFilePath, \ + AprioriFileGuid + FvName + '.Apri' ) + AprFfsFileName = os.path.join (OutputAprFilePath,\ + AprioriFileGuid + FvName + '.Ffs') + + Dict.update(self.DefineVarDict) + for FfsObj in self.FfsList : + Guid = "" + if isinstance(FfsObj, FfsFileStatement.FileStatement): + Guid = FfsObj.NameGuid + else: + InfFileName = NormPath(FfsObj.InfFileName) + Arch = FfsObj.GetCurrentArch() + + if Arch != None: + Dict['$(ARCH)'] = Arch + InfFileName = GenFdsGlobalVariable.MacroExtend(InfFileName, Dict, Arch) + + if Arch != None: + Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(InfFileName, GenFdsGlobalVariable.WorkSpaceDir), Arch] + Guid = Inf.Guid + + else: + Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(InfFileName, GenFdsGlobalVariable.WorkSpaceDir), 'COMMON'] + Guid = Inf.Guid + + self.BinFileList = Inf.Module.Binaries + if self.BinFileList == []: + EdkLogger.error("GenFds", RESOURCE_NOT_AVAILABLE, + "INF %s not found in build ARCH %s!" \ + % (InfFileName, GenFdsGlobalVariable.ArchList)) + + + GuidPart = Guid.split('-') + Buffer.write(pack('I', long(GuidPart[0], 16))) + Buffer.write(pack('H', int(GuidPart[1], 16))) + Buffer.write(pack('H', int(GuidPart[2], 16))) + + for Num in range(2): + Char = GuidPart[3][Num*2:Num*2+2] + Buffer.write(pack('B', int(Char, 16))) + + for Num in range(6): + Char = GuidPart[4][Num*2:Num*2+2] + Buffer.write(pack('B', int(Char, 16))) + + SaveFileOnChange(OutputAprFileName, Buffer.getvalue()) + + RawSectionFileName = os.path.join( OutputAprFilePath, \ + AprioriFileGuid + FvName + '.raw' ) + GenFdsGlobalVariable.GenerateSection(RawSectionFileName, [OutputAprFileName], 'EFI_SECTION_RAW') + GenFdsGlobalVariable.GenerateFfs(AprFfsFileName, [RawSectionFileName], + 'EFI_FV_FILETYPE_FREEFORM', AprioriFileGuid) + + return AprFfsFileName + diff --git a/BaseTools/Source/Python/GenFds/Attribute.py b/BaseTools/Source/Python/GenFds/Attribute.py new file mode 100644 index 0000000000..67f9956e1d --- /dev/null +++ b/BaseTools/Source/Python/GenFds/Attribute.py @@ -0,0 +1,28 @@ +## @file +# name value pair +# +# Copyright (c) 2007, 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 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 +# + +## name value pair +# +# +class Attribute: + ## The constructor + # + # @param self The object pointer + def __init__(self): + self.Name = None + self.Value = None \ No newline at end of file diff --git a/BaseTools/Source/Python/GenFds/Capsule.py b/BaseTools/Source/Python/GenFds/Capsule.py new file mode 100644 index 0000000000..7f17fcda68 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/Capsule.py @@ -0,0 +1,89 @@ +## @file +# generate capsule +# +# Copyright (c) 2007, 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 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 +# +from GenFdsGlobalVariable import GenFdsGlobalVariable +from CommonDataClass.FdfClass import CapsuleClassObject +import os +import subprocess +import StringIO +from Common.Misc import SaveFileOnChange + + +T_CHAR_LF = '\n' + +## create inf file describes what goes into capsule and call GenFv to generate capsule +# +# +class Capsule (CapsuleClassObject) : + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + CapsuleClassObject.__init__(self) + # For GenFv + self.BlockSize = None + # For GenFv + self.BlockNum = None + + ## Generate capsule + # + # @param self The object pointer + # + def GenCapsule(self): + CapInfFile = self.GenCapInf() + CapInfFile.writelines("[files]" + T_CHAR_LF) + + for CapsuleDataObj in self.CapsuleDataList : + FileName = CapsuleDataObj.GenCapsuleSubItem() + CapInfFile.writelines("EFI_FILE_NAME = " + \ + FileName + \ + T_CHAR_LF) + SaveFileOnChange(self.CapInfFileName, CapInfFile.getvalue(), False) + CapInfFile.close() + # + # Call GenFv tool to generate capsule + # + CapOutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.UiCapsuleName) + CapOutputFile = CapOutputFile + '.Cap' + GenFdsGlobalVariable.GenerateFirmwareVolume( + CapOutputFile, + [self.CapInfFileName], + Capsule=True + ) + GenFdsGlobalVariable.SharpCounter = 0 + + ## Generate inf file for capsule + # + # @param self The object pointer + # @retval file inf file object + # + def GenCapInf(self): + self.CapInfFileName = os.path.join(GenFdsGlobalVariable.FvDir, + self.UiCapsuleName + "_Cap" + '.inf') + CapInfFile = StringIO.StringIO() #open (self.CapInfFileName , 'w+') + + CapInfFile.writelines("[options]" + T_CHAR_LF) + + for Item in self.TokensDict.keys(): + CapInfFile.writelines("EFI_" + \ + Item + \ + ' = ' + \ + self.TokensDict.get(Item) + \ + T_CHAR_LF) + + return CapInfFile diff --git a/BaseTools/Source/Python/GenFds/CapsuleData.py b/BaseTools/Source/Python/GenFds/CapsuleData.py new file mode 100644 index 0000000000..db29737963 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/CapsuleData.py @@ -0,0 +1,84 @@ +## @file +# generate capsule +# +# Copyright (c) 2007, 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 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 Ffs +from GenFdsGlobalVariable import GenFdsGlobalVariable +import StringIO + +## base class for capsule data +# +# +class CapsuleData: + ## The constructor + # + # @param self The object pointer + def __init__(self): + pass + + ## generate capsule data + # + # @param self The object pointer + def GenCapsuleSubItem(self): + pass + +## FFS class for capsule data +# +# +class CapsuleFfs (CapsuleData): + ## The constructor + # + # @param self The object pointer + # + def __init_(self) : + self.Ffs = None + + ## generate FFS capsule data + # + # @param self The object pointer + # @retval string Generated file name + # + def GenCapsuleSubItem(self): + FfsFile = self.Ffs.GenFfs() + return FfsFile + +## FV class for capsule data +# +# +class CapsuleFv (CapsuleData): + ## The constructor + # + # @param self The object pointer + # + def __init__(self) : + self.FvName = None + + ## generate FV capsule data + # + # @param self The object pointer + # @retval string Generated file name + # + def GenCapsuleSubItem(self): + if self.FvName.find('.fv') == -1: + if self.FvName.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys(): + FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName.upper()) + FdBuffer = StringIO.StringIO('') + FvFile = FvObj.AddToBuffer(FdBuffer) + return FvFile + + else: + FvFile = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FvName) + return FvFile diff --git a/BaseTools/Source/Python/GenFds/ComponentStatement.py b/BaseTools/Source/Python/GenFds/ComponentStatement.py new file mode 100644 index 0000000000..8a7540fe25 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/ComponentStatement.py @@ -0,0 +1,29 @@ +## @file +# VTF components +# +# Copyright (c) 2007, 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 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 +# +from CommonDataClass.FdfClass import ComponentStatementClassObject + +## VTF components +# +# +class ComponentStatement (ComponentStatementClassObject) : + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + ComponentStatementClassObject.__init__(self) diff --git a/BaseTools/Source/Python/GenFds/CompressSection.py b/BaseTools/Source/Python/GenFds/CompressSection.py new file mode 100644 index 0000000000..4a32ea4458 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/CompressSection.py @@ -0,0 +1,87 @@ +## @file +# process compress section generation +# +# Copyright (c) 2007, 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 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 +# +from Ffs import Ffs +import Section +import subprocess +import os +from GenFdsGlobalVariable import GenFdsGlobalVariable +from CommonDataClass.FdfClass import CompressSectionClassObject + +## generate compress section +# +# +class CompressSection (CompressSectionClassObject) : + + ## compress types: PI standard and non PI standard + CompTypeDict = { + 'PI_STD' : 'PI_STD', + 'NON_PI_STD' : 'NON_PI_STD' + } + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + CompressSectionClassObject.__init__(self) + + ## GenSection() method + # + # Generate compressed section + # + # @param self The object pointer + # @param OutputPath Where to place output file + # @param ModuleName Which module this section belongs to + # @param SecNum Index of section + # @param KeyStringList Filter for inputs of section generation + # @param FfsInf FfsInfStatement object that contains this section data + # @param Dict dictionary contains macro and its value + # @retval tuple (Generated file name, section alignment) + # + def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}): + + if FfsInf != None: + self.CompType = FfsInf.__ExtendMacro__(self.CompType) + self.Alignment = FfsInf.__ExtendMacro__(self.Alignment) + + SectFiles = tuple() + Index = 0 + for Sect in self.SectionList: + Index = Index + 1 + SecIndex = '%s.%d' %(SecNum, Index) + ReturnSectList, AlignValue = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict) + if ReturnSectList != []: + for FileData in ReturnSectList: + SectFiles += (FileData,) + + + OutputFile = OutputPath + \ + os.sep + \ + ModuleName + \ + 'SEC' + \ + SecNum + \ + Ffs.SectionSuffix['COMPRESS'] + OutputFile = os.path.normpath(OutputFile) + + GenFdsGlobalVariable.GenerateSection(OutputFile, SectFiles, Section.Section.SectionType['COMPRESS'], + CompressionType=self.CompTypeDict[self.CompType]) + OutputFileList = [] + OutputFileList.append(OutputFile) + return OutputFileList, self.Alignment + + diff --git a/BaseTools/Source/Python/GenFds/DataSection.py b/BaseTools/Source/Python/GenFds/DataSection.py new file mode 100644 index 0000000000..7f24b51fc3 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/DataSection.py @@ -0,0 +1,109 @@ +## @file +# process data section generation +# +# Copyright (c) 2007, 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 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 Section +from GenFdsGlobalVariable import GenFdsGlobalVariable +import subprocess +from Ffs import Ffs +import os +from CommonDataClass.FdfClass import DataSectionClassObject +import shutil + +## generate data section +# +# +class DataSection (DataSectionClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + DataSectionClassObject.__init__(self) + + ## GenSection() method + # + # Generate compressed section + # + # @param self The object pointer + # @param OutputPath Where to place output file + # @param ModuleName Which module this section belongs to + # @param SecNum Index of section + # @param KeyStringList Filter for inputs of section generation + # @param FfsInf FfsInfStatement object that contains this section data + # @param Dict dictionary contains macro and its value + # @retval tuple (Generated file name list, section alignment) + # + def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = None, Dict = {}): + # + # Prepare the parameter of GenSection + # + if FfsFile != None: + self.SectFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.SectFileName) + self.SectFileName = GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict, FfsFile.CurrentArch) + else: + self.SectFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.SectFileName) + self.SectFileName = GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict) + + """Check Section file exist or not !""" + + if not os.path.exists(self.SectFileName): + self.SectFileName = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, + self.SectFileName) + + """Copy Map file to Ffs output""" + Filename = GenFdsGlobalVariable.MacroExtend(self.SectFileName) + if Filename[(len(Filename)-4):] == '.efi': + MapFile = Filename.replace('.efi', '.map') + if os.path.exists(MapFile): + CopyMapFile = os.path.join(OutputPath, ModuleName + '.map') + if not os.path.exists(CopyMapFile) or \ + (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)): + shutil.copyfile(MapFile, CopyMapFile) + + NoStrip = True + if self.SecType in ('TE', 'PE32'): + if self.KeepReloc != None: + NoStrip = self.KeepReloc + + if not NoStrip: + FileBeforeStrip = os.path.join(OutputPath, ModuleName + '.efi') + if not os.path.exists(FileBeforeStrip) or \ + (os.path.getmtime(self.SectFileName) > os.path.getmtime(FileBeforeStrip)): + shutil.copyfile(self.SectFileName, FileBeforeStrip) + StrippedFile = os.path.join(OutputPath, ModuleName + '.stripped') + GenFdsGlobalVariable.GenerateFirmwareImage( + StrippedFile, + [GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)], + Strip=True + ) + self.SectFileName = StrippedFile + + if self.SecType == 'TE': + TeFile = os.path.join( OutputPath, ModuleName + 'Te.raw') + GenFdsGlobalVariable.GenerateFirmwareImage( + TeFile, + [GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)], + Type='te' + ) + self.SectFileName = TeFile + + OutputFile = os.path.join (OutputPath, ModuleName + 'SEC' + SecNum + Ffs.SectionSuffix.get(self.SecType)) + OutputFile = os.path.normpath(OutputFile) + + GenFdsGlobalVariable.GenerateSection(OutputFile, [self.SectFileName], Section.Section.SectionType.get(self.SecType)) + FileList = [OutputFile] + return FileList, self.Alignment diff --git a/BaseTools/Source/Python/GenFds/DepexSection.py b/BaseTools/Source/Python/GenFds/DepexSection.py new file mode 100644 index 0000000000..1c8c82a72e --- /dev/null +++ b/BaseTools/Source/Python/GenFds/DepexSection.py @@ -0,0 +1,102 @@ +## @file +# process depex section generation +# +# Copyright (c) 2007, 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 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 Section +from GenFdsGlobalVariable import GenFdsGlobalVariable +import subprocess +from Ffs import Ffs +import os +from CommonDataClass.FdfClass import DepexSectionClassObject +from AutoGen.GenDepex import DependencyExpression +import shutil +from Common import EdkLogger +from Common.BuildToolError import * + +## generate data section +# +# +class DepexSection (DepexSectionClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + DepexSectionClassObject.__init__(self) + + def __FindGuidValue(self, CName): + for Arch in GenFdsGlobalVariable.ArchList: + for PkgDb in GenFdsGlobalVariable.WorkSpace.PackageList: + if CName in PkgDb.Ppis: + return PkgDb.Ppis[CName] + if CName in PkgDb.Protocols: + return PkgDb.Protocols[CName] + if CName in PkgDb.Guids: + return PkgDb.Guids[CName] + return None + + ## GenSection() method + # + # Generate compressed section + # + # @param self The object pointer + # @param OutputPath Where to place output file + # @param ModuleName Which module this section belongs to + # @param SecNum Index of section + # @param KeyStringList Filter for inputs of section generation + # @param FfsInf FfsInfStatement object that contains this section data + # @param Dict dictionary contains macro and its value + # @retval tuple (Generated file name list, section alignment) + # + def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = None, Dict = {}): + + self.Expression = self.Expression.replace("\n", " ").replace("\r", " ") + ExpList = self.Expression.split() + ExpGuidDict = {} + + for Exp in ExpList: + if Exp.upper() not in ('AND', 'OR', 'NOT', 'TRUE', 'FALSE', 'SOR', 'BEFORE', 'AFTER', 'END'): + GuidStr = self.__FindGuidValue(Exp) + if GuidStr == None: + EdkLogger.error("GenFds", RESOURCE_NOT_AVAILABLE, + "Depex GUID %s could not be found in build DB! (ModuleName: %s)" % (Exp, ModuleName)) + + ExpGuidDict[Exp] = GuidStr + + for Item in ExpGuidDict: + self.Expression = self.Expression.replace(Item, ExpGuidDict[Item]) + + self.Expression = self.Expression.strip() + ModuleType = (self.DepexType.startswith('PEI') and ['PEIM'] or ['DXE_DRIVER'])[0] + if self.DepexType.startswith('SMM'): + ModuleType = 'SMM_DRIVER' + InputFile = os.path.join (OutputPath, ModuleName + 'SEC' + SecNum + '.dpx') + InputFile = os.path.normpath(InputFile) + + Dpx = DependencyExpression(self.Expression, ModuleType) + Dpx.Generate(InputFile) + + OutputFile = os.path.join (OutputPath, ModuleName + 'SEC' + SecNum + '.depex') + if self.DepexType.startswith('SMM'): + OutputFile = os.path.join (OutputPath, ModuleName + 'SEC' + SecNum + '.smm') + OutputFile = os.path.normpath(OutputFile) + SecType = (self.DepexType.startswith('PEI') and ['PEI_DEPEX'] or ['DXE_DEPEX'])[0] + if self.DepexType.startswith('SMM'): + SecType = 'SMM_DEPEX' + + GenFdsGlobalVariable.GenerateSection(OutputFile, [InputFile], Section.Section.SectionType.get (SecType)) + FileList = [OutputFile] + return FileList, self.Alignment diff --git a/BaseTools/Source/Python/GenFds/EfiSection.py b/BaseTools/Source/Python/GenFds/EfiSection.py new file mode 100644 index 0000000000..2c112ed5cb --- /dev/null +++ b/BaseTools/Source/Python/GenFds/EfiSection.py @@ -0,0 +1,262 @@ +## @file +# process rule section generation +# +# Copyright (c) 2007, 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 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 Section +from GenFdsGlobalVariable import GenFdsGlobalVariable +import subprocess +from Ffs import Ffs +import os +from CommonDataClass.FdfClass import EfiSectionClassObject +import shutil +from Common import EdkLogger +from Common.BuildToolError import * + +## generate rule section +# +# +class EfiSection (EfiSectionClassObject): + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + EfiSectionClassObject.__init__(self) + + ## GenSection() method + # + # Generate rule section + # + # @param self The object pointer + # @param OutputPath Where to place output file + # @param ModuleName Which module this section belongs to + # @param SecNum Index of section + # @param KeyStringList Filter for inputs of section generation + # @param FfsInf FfsInfStatement object that contains this section data + # @param Dict dictionary contains macro and its value + # @retval tuple (Generated file name list, section alignment) + # + def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}) : + + if self.FileName != None and self.FileName.startswith('PCD('): + self.FileName = GenFdsGlobalVariable.GetPcdValue(self.FileName) + """Prepare the parameter of GenSection""" + if FfsInf != None : + InfFileName = FfsInf.InfFileName + SectionType = FfsInf.__ExtendMacro__(self.SectionType) + Filename = FfsInf.__ExtendMacro__(self.FileName) + BuildNum = FfsInf.__ExtendMacro__(self.BuildNum) + StringData = FfsInf.__ExtendMacro__(self.StringData) + NoStrip = True + if FfsInf.ModuleType in ('SEC', 'PEI_CORE', 'PEIM') and SectionType in ('TE', 'PE32'): + if FfsInf.KeepReloc != None: + NoStrip = FfsInf.KeepReloc + elif FfsInf.KeepRelocFromRule != None: + NoStrip = FfsInf.KeepRelocFromRule + elif self.KeepReloc != None: + NoStrip = self.KeepReloc + elif FfsInf.ShadowFromInfFile != None: + NoStrip = FfsInf.ShadowFromInfFile + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s apply rule for None!" %ModuleName) + + """If the file name was pointed out, add it in FileList""" + FileList = [] + if Filename != None: + Filename = GenFdsGlobalVariable.MacroExtend(Filename, Dict) + if not self.Optional: + FileList.append(Filename) + elif os.path.exists(Filename): + FileList.append(Filename) + else: + FileList, IsSect = Section.Section.GetFileList(FfsInf, self.FileType, self.FileExtension, Dict) + if IsSect : + return FileList, self.Alignment + + Index = 0 + + """ If Section type is 'VERSION'""" + OutputFileList = [] + if SectionType == 'VERSION': + + InfOverrideVerString = False + if FfsInf.Version != None: + #StringData = FfsInf.Version + BuildNum = FfsInf.Version + InfOverrideVerString = True + + if InfOverrideVerString: + #VerTuple = ('-n', '"' + StringData + '"') + if BuildNum != None and BuildNum != '': + BuildNumTuple = ('-j', BuildNum) + else: + BuildNumTuple = tuple() + + Num = SecNum + OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType)) + GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION', + #Ui=StringData, + Ver=BuildNum) + OutputFileList.append(OutputFile) + + elif FileList != []: + for File in FileList: + Index = Index + 1 + Num = '%s.%d' %(SecNum , Index) + OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + Num + Ffs.SectionSuffix.get(SectionType)) + f = open(File, 'r') + VerString = f.read() + f.close() +# VerTuple = ('-n', '"' + VerString + '"') + BuildNum = VerString + if BuildNum != None and BuildNum != '': + BuildNumTuple = ('-j', BuildNum) + GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION', + #Ui=VerString, + Ver=BuildNum) + OutputFileList.append(OutputFile) + + else: +# if StringData != None and len(StringData) > 0: +# VerTuple = ('-n', '"' + StringData + '"') +# else: +# VerTuple = tuple() +# VerString = ' ' + ' '.join(VerTuple) + BuildNum = StringData + if BuildNum != None and BuildNum != '': + BuildNumTuple = ('-j', BuildNum) + else: + BuildNumTuple = tuple() + BuildNumString = ' ' + ' '.join(BuildNumTuple) + + #if VerString == '' and + if BuildNumString == '': + if self.Optional == True : + GenFdsGlobalVariable.VerboseLogger( "Optional Section don't exist!") + return [], None + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "File: %s miss Version Section value" %InfFileName) + Num = SecNum + OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType)) + GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION', + #Ui=VerString, + Ver=BuildNum) + OutputFileList.append(OutputFile) + + # + # If Section Type is 'UI' + # + elif SectionType == 'UI': + + InfOverrideUiString = False + if FfsInf.Ui != None: + StringData = FfsInf.Ui + InfOverrideUiString = True + + if InfOverrideUiString: + Num = SecNum + OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType)) + GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE', + Ui=StringData) + OutputFileList.append(OutputFile) + + elif FileList != []: + for File in FileList: + Index = Index + 1 + Num = '%s.%d' %(SecNum , Index) + OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + Num + Ffs.SectionSuffix.get(SectionType)) + f = open(File, 'r') + UiString = f.read() + f.close() + GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE', + Ui=UiString) + OutputFileList.append(OutputFile) + else: + if StringData != None and len(StringData) > 0: + UiTuple = ('-n', '"' + StringData + '"') + else: + UiTuple = tuple() + + if self.Optional == True : + GenFdsGlobalVariable.VerboseLogger( "Optional Section don't exist!") + return '', None + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "File: %s miss UI Section value" %InfFileName) + + Num = SecNum + OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType)) + GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE', + Ui=StringData) + OutputFileList.append(OutputFile) + + + else: + """If File List is empty""" + if FileList == [] : + if self.Optional == True: + GenFdsGlobalVariable.VerboseLogger( "Optional Section don't exist!") + return [], None + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "Output file for %s section could not be found for %s" % (SectionType, InfFileName)) + + else: + """Convert the File to Section file one by one """ + for File in FileList: + """ Copy Map file to FFS output path """ + Index = Index + 1 + Num = '%s.%d' %(SecNum , Index) + OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + Num + Ffs.SectionSuffix.get(SectionType)) + File = GenFdsGlobalVariable.MacroExtend(File, Dict) + if File[(len(File)-4):] == '.efi': + MapFile = File.replace('.efi', '.map') + if os.path.exists(MapFile): + CopyMapFile = os.path.join(OutputPath, ModuleName + '.map') + if not os.path.exists(CopyMapFile) or \ + (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)): + shutil.copyfile(MapFile, CopyMapFile) + + if not NoStrip: + FileBeforeStrip = os.path.join(OutputPath, ModuleName + '.efi') + if not os.path.exists(FileBeforeStrip) or \ + (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)): + shutil.copyfile(File, FileBeforeStrip) + StrippedFile = os.path.join(OutputPath, ModuleName + '.stripped') + GenFdsGlobalVariable.GenerateFirmwareImage( + StrippedFile, + [GenFdsGlobalVariable.MacroExtend(File, Dict)], + Strip=True + ) + File = StrippedFile + """For TE Section call GenFw to generate TE image""" + + if SectionType == 'TE': + TeFile = os.path.join( OutputPath, ModuleName + 'Te.raw') + GenFdsGlobalVariable.GenerateFirmwareImage( + TeFile, + [GenFdsGlobalVariable.MacroExtend(File, Dict)], + Type='te' + ) + File = TeFile + + """Call GenSection""" + GenFdsGlobalVariable.GenerateSection(OutputFile, + [GenFdsGlobalVariable.MacroExtend(File)], + Section.Section.SectionType.get (SectionType) + ) + OutputFileList.append(OutputFile) + + return OutputFileList, self.Alignment diff --git a/BaseTools/Source/Python/GenFds/Fd.py b/BaseTools/Source/Python/GenFds/Fd.py new file mode 100644 index 0000000000..99baa6abe5 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/Fd.py @@ -0,0 +1,169 @@ +## @file +# process FD generation +# +# Copyright (c) 2007, 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 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 Region +import Fv +import os +import StringIO +import sys +from struct import * +from GenFdsGlobalVariable import GenFdsGlobalVariable +from CommonDataClass.FdfClass import FDClassObject +from Common import EdkLogger +from Common.BuildToolError import * +from Common.Misc import SaveFileOnChange + +## generate FD +# +# +class FD(FDClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + FDClassObject.__init__(self) + + ## GenFd() method + # + # Generate FD + # + # @param self The object pointer + # @param FvBinDict dictionary contains generated FV name and its file name + # @retval string Generated FD file name + # + def GenFd (self, FvBinDict): + # + # Print Information + # + GenFdsGlobalVariable.InfLogger("Fd File Name:%s" %self.FdUiName) + Offset = 0x00 + for item in self.BlockSizeList: + Offset = Offset + item[0] * item[1] + if Offset != self.Size: + EdkLogger.error("GenFds", GENFDS_ERROR, 'FD %s Size not consistent with block array' % self.FdUiName) + GenFdsGlobalVariable.VerboseLogger('Following Fv will be add to Fd !!!') + for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict: + GenFdsGlobalVariable.VerboseLogger(FvObj) + + GenFdsGlobalVariable.VerboseLogger('################### Gen VTF ####################') + self.GenVtfFile() + + FdBuffer = StringIO.StringIO('') + PreviousRegionStart = -1 + PreviousRegionSize = 1 + for RegionObj in self.RegionList : + if RegionObj.Offset + RegionObj.Size <= PreviousRegionStart: + EdkLogger.error("GenFds", GENFDS_ERROR, + 'Region offset 0x%X in wrong order with Region starting from 0x%X, size 0x%X\nRegions in FDF must have offsets appear in ascending order.'\ + % (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize)) + elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize): + EdkLogger.error("GenFds", GENFDS_ERROR, + 'Region offset 0x%X overlaps with Region starting from 0x%X, size 0x%X' \ + % (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize)) + elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize: + GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize))) + PadRegion = Region.Region() + PadRegion.Offset = PreviousRegionStart + PreviousRegionSize + PadRegion.Size = RegionObj.Offset - PadRegion.Offset + PadRegion.AddToBuffer(FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, FvBinDict, self.vtfRawDict, self.DefineVarDict) + PreviousRegionStart = RegionObj.Offset + PreviousRegionSize = RegionObj.Size + # + # Call each region's AddToBuffer function + # + if PreviousRegionSize > self.Size: + EdkLogger.error("GenFds", GENFDS_ERROR, 'FD %s size too small' % self.FdUiName) + GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function') + RegionObj.AddToBuffer (FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, FvBinDict, self.vtfRawDict, self.DefineVarDict) + # + # Create a empty Fd file + # + GenFdsGlobalVariable.VerboseLogger ('Create an empty Fd file') + FdFileName = os.path.join(GenFdsGlobalVariable.FvDir, + self.FdUiName + '.fd') + #FdFile = open(FdFileName, 'wb') + + # + # Write the buffer contents to Fd file + # + GenFdsGlobalVariable.VerboseLogger('Write the buffer contents to Fd file') + SaveFileOnChange(FdFileName, FdBuffer.getvalue()) + #FdFile.write(FdBuffer.getvalue()); + #FdFile.close(); + FdBuffer.close(); + return FdFileName + + ## generate VTF + # + # @param self The object pointer + # + def GenVtfFile (self) : + # + # Get this Fd's all Fv name + # + FvAddDict ={} + FvList = [] + for RegionObj in self.RegionList: + if RegionObj.RegionType == 'FV': + if len(RegionObj.RegionDataList) == 1: + RegionData = RegionObj.RegionDataList[0] + FvList.append(RegionData.upper()) + FvAddDict[RegionData.upper()] = (int(self.BaseAddress,16) + \ + RegionObj.Offset, RegionObj.Size) + else: + Offset = RegionObj.Offset + for RegionData in RegionObj.RegionDataList: + FvList.append(RegionData.upper()) + FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(RegionData.upper()) + if len(FvObj.BlockSizeList) < 1: + EdkLogger.error("GenFds", GENFDS_ERROR, + 'FV.%s must point out FVs blocksize and Fv BlockNum' \ + % FvObj.UiFvName) + else: + Size = 0 + for blockStatement in FvObj.BlockSizeList: + Size = Size + blockStatement[0] * blockStatement[1] + FvAddDict[RegionData.upper()] = (int(self.BaseAddress,16) + \ + Offset, Size) + Offset = Offset + Size + # + # Check whether this Fd need VTF + # + Flag = False + for VtfObj in GenFdsGlobalVariable.FdfParser.Profile.VtfList: + compLocList = VtfObj.GetFvList() + if set(compLocList).issubset(FvList): + Flag = True + break + if Flag == True: + self.vtfRawDict = VtfObj.GenVtf(FvAddDict) + + ## generate flash map file + # + # @param self The object pointer + # + def GenFlashMap (self): + pass + + + + + + + + diff --git a/BaseTools/Source/Python/GenFds/FdfParser.py b/BaseTools/Source/Python/GenFds/FdfParser.py new file mode 100644 index 0000000000..0bf8f5514b --- /dev/null +++ b/BaseTools/Source/Python/GenFds/FdfParser.py @@ -0,0 +1,3778 @@ +## @file +# parse FDF file +# +# Copyright (c) 2007, 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 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 Fd +import Region +import Fv +import AprioriSection +import FfsInfStatement +import FfsFileStatement +import VerSection +import UiSection +import FvImageSection +import DataSection +import DepexSection +import CompressSection +import GuidSection +import Capsule +import CapsuleData +import Rule +import RuleComplexFile +import RuleSimpleFile +import EfiSection +import Vtf +import ComponentStatement +import OptionRom +import OptRomInfStatement +import OptRomFileStatement + +from Common.BuildToolError import * +from Common import EdkLogger + +import re +import os + +##define T_CHAR_SPACE ' ' +##define T_CHAR_NULL '\0' +##define T_CHAR_CR '\r' +##define T_CHAR_TAB '\t' +##define T_CHAR_LF '\n' +##define T_CHAR_SLASH '/' +##define T_CHAR_BACKSLASH '\\' +##define T_CHAR_DOUBLE_QUOTE '\"' +##define T_CHAR_SINGLE_QUOTE '\'' +##define T_CHAR_STAR '*' +##define T_CHAR_HASH '#' + +(T_CHAR_SPACE, T_CHAR_NULL, T_CHAR_CR, T_CHAR_TAB, T_CHAR_LF, T_CHAR_SLASH, \ +T_CHAR_BACKSLASH, T_CHAR_DOUBLE_QUOTE, T_CHAR_SINGLE_QUOTE, T_CHAR_STAR, T_CHAR_HASH) = \ +(' ', '\0', '\r', '\t', '\n', '/', '\\', '\"', '\'', '*', '#') + +SEPERATOR_TUPLE = ('=', '|', ',', '{', '}') + +IncludeFileList = [] +# Macro passed from command line, which has greatest priority and can NOT be overridden by those in FDF +InputMacroDict = {} +# All Macro values when parsing file, not replace existing Macro +AllMacroList = [] + +def GetRealFileLine (File, Line): + + InsertedLines = 0 + for Profile in IncludeFileList: + if Line >= Profile.InsertStartLineNumber and Line < Profile.InsertStartLineNumber + Profile.InsertAdjust + len(Profile.FileLinesList): + return (Profile.FileName, Line - Profile.InsertStartLineNumber + 1) + if Line >= Profile.InsertStartLineNumber + Profile.InsertAdjust + len(Profile.FileLinesList): + InsertedLines += Profile.InsertAdjust + len(Profile.FileLinesList) + + return (File, Line - InsertedLines) + +## The exception class that used to report error messages when parsing FDF +# +# Currently the "ToolName" is set to be "FDF Parser". +# +class Warning (Exception): + ## The constructor + # + # @param self The object pointer + # @param Str The message to record + # @param File The FDF name + # @param Line The Line number that error occurs + # + def __init__(self, Str, File = None, Line = None): + + FileLineTuple = GetRealFileLine(File, Line) + self.FileName = FileLineTuple[0] + self.LineNumber = FileLineTuple[1] + self.Message = Str + self.ToolName = 'FdfParser' + + def __str__(self): + return self.Message + +## The MACRO class that used to record macro value data when parsing include file +# +# +class MacroProfile : + ## The constructor + # + # @param self The object pointer + # @param FileName The file that to be parsed + # + def __init__(self, FileName, Line): + self.FileName = FileName + self.DefinedAtLine = Line + self.MacroName = None + self.MacroValue = None + +## The Include file content class that used to record file data when parsing include file +# +# May raise Exception when opening file. +# +class IncludeFileProfile : + ## The constructor + # + # @param self The object pointer + # @param FileName The file that to be parsed + # + def __init__(self, FileName): + self.FileName = FileName + self.FileLinesList = [] + try: + fsock = open(FileName, "rb", 0) + try: + self.FileLinesList = fsock.readlines() + finally: + fsock.close() + + except: + EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName) + + self.InsertStartLineNumber = None + self.InsertAdjust = 0 + +## The FDF content class that used to record file data when parsing FDF +# +# May raise Exception when opening file. +# +class FileProfile : + ## The constructor + # + # @param self The object pointer + # @param FileName The file that to be parsed + # + def __init__(self, FileName): + self.FileLinesList = [] + try: + fsock = open(FileName, "rb", 0) + try: + self.FileLinesList = fsock.readlines() + finally: + fsock.close() + + except: + EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName) + + + self.PcdDict = {} + self.InfList = [] + + self.FdDict = {} + self.FvDict = {} + self.CapsuleList = [] + self.VtfList = [] + self.RuleDict = {} + self.OptRomDict = {} + +## The syntax parser for FDF +# +# PreprocessFile method should be called prior to ParseFile +# CycleReferenceCheck method can detect cycles in FDF contents +# +# GetNext*** procedures mean these procedures will get next token first, then make judgement. +# Get*** procedures mean these procedures will make judgement on current token only. +# +class FdfParser: + ## The constructor + # + # @param self The object pointer + # @param FileName The file that to be parsed + # + def __init__(self, FileName): + self.Profile = FileProfile(FileName) + self.FileName = FileName + self.CurrentLineNumber = 1 + self.CurrentOffsetWithinLine = 0 + self.CurrentFdName = None + self.CurrentFvName = None + self.__Token = "" + self.__SkippedChars = "" + + self.__WipeOffArea = [] + + ## __IsWhiteSpace() method + # + # Whether char at current FileBufferPos is whitespace + # + # @param self The object pointer + # @param Char The char to test + # @retval True The char is a kind of white space + # @retval False The char is NOT a kind of white space + # + def __IsWhiteSpace(self, Char): + if Char in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_SPACE, T_CHAR_TAB, T_CHAR_LF): + return True + else: + return False + + ## __SkipWhiteSpace() method + # + # Skip white spaces from current char, return number of chars skipped + # + # @param self The object pointer + # @retval Count The number of chars skipped + # + def __SkipWhiteSpace(self): + Count = 0 + while not self.__EndOfFile(): + Count += 1 + if self.__CurrentChar() in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_LF, T_CHAR_SPACE, T_CHAR_TAB): + self.__SkippedChars += str(self.__CurrentChar()) + self.__GetOneChar() + + else: + Count = Count - 1 + return Count + + ## __EndOfFile() method + # + # Judge current buffer pos is at file end + # + # @param self The object pointer + # @retval True Current File buffer position is at file end + # @retval False Current File buffer position is NOT at file end + # + def __EndOfFile(self): + NumberOfLines = len(self.Profile.FileLinesList) + SizeOfLastLine = len(self.Profile.FileLinesList[-1]) + if self.CurrentLineNumber == NumberOfLines and self.CurrentOffsetWithinLine >= SizeOfLastLine - 1: + return True + elif self.CurrentLineNumber > NumberOfLines: + return True + else: + return False + + ## __EndOfLine() method + # + # Judge current buffer pos is at line end + # + # @param self The object pointer + # @retval True Current File buffer position is at line end + # @retval False Current File buffer position is NOT at line end + # + def __EndOfLine(self): + if self.CurrentLineNumber > len(self.Profile.FileLinesList): + return True + SizeOfCurrentLine = len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) + if self.CurrentOffsetWithinLine >= SizeOfCurrentLine: + return True + else: + return False + + ## Rewind() method + # + # Reset file data buffer to the initial state + # + # @param self The object pointer + # + def Rewind(self): + self.CurrentLineNumber = 1 + self.CurrentOffsetWithinLine = 0 + + ## __UndoOneChar() method + # + # Go back one char in the file buffer + # + # @param self The object pointer + # @retval True Successfully go back one char + # @retval False Not able to go back one char as file beginning reached + # + def __UndoOneChar(self): + + if self.CurrentLineNumber == 1 and self.CurrentOffsetWithinLine == 0: + return False + elif self.CurrentOffsetWithinLine == 0: + self.CurrentLineNumber -= 1 + self.CurrentOffsetWithinLine = len(self.__CurrentLine()) - 1 + else: + self.CurrentOffsetWithinLine -= 1 + return True + + ## __GetOneChar() method + # + # Move forward one char in the file buffer + # + # @param self The object pointer + # + def __GetOneChar(self): + if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1: + self.CurrentLineNumber += 1 + self.CurrentOffsetWithinLine = 0 + else: + self.CurrentOffsetWithinLine += 1 + + ## __CurrentChar() method + # + # Get the char pointed to by the file buffer pointer + # + # @param self The object pointer + # @retval Char Current char + # + def __CurrentChar(self): + return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] + + ## __NextChar() method + # + # Get the one char pass the char pointed to by the file buffer pointer + # + # @param self The object pointer + # @retval Char Next char + # + def __NextChar(self): + if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1: + return self.Profile.FileLinesList[self.CurrentLineNumber][0] + else: + return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine + 1] + + ## __SetCurrentCharValue() method + # + # Modify the value of current char + # + # @param self The object pointer + # @param Value The new value of current char + # + def __SetCurrentCharValue(self, Value): + self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] = Value + + ## __CurrentLine() method + # + # Get the list that contains current line contents + # + # @param self The object pointer + # @retval List current line contents + # + def __CurrentLine(self): + return self.Profile.FileLinesList[self.CurrentLineNumber - 1] + + def __StringToList(self): + self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesList] + self.Profile.FileLinesList[-1].append(' ') + + def __ReplaceMacros(self, Str, File, Line): + MacroEnd = 0 + while Str.find('$(', MacroEnd) >= 0: + MacroStart = Str.find('$(', MacroEnd) + if Str.find(')', MacroStart) > 0: + MacroEnd = Str.find(')', MacroStart) + Name = Str[MacroStart + 2 : MacroEnd] + Value = None + if Name in InputMacroDict: + Value = InputMacroDict[Name] + + else: + for Profile in AllMacroList: + if Profile.FileName == File and Profile.MacroName == Name and Profile.DefinedAtLine <= Line: + Value = Profile.MacroValue + + if Value != None: + Str = Str.replace('$(' + Name + ')', Value) + MacroEnd = MacroStart + len(Value) + + else: + raise Warning("Macro not complete", self.FileName, self.CurrentLineNumber) + return Str + + def __ReplaceFragment(self, StartPos, EndPos, Value = ' '): + if StartPos[0] == EndPos[0]: + Offset = StartPos[1] + while Offset <= EndPos[1]: + self.Profile.FileLinesList[StartPos[0]][Offset] = Value + Offset += 1 + return + + Offset = StartPos[1] + while self.Profile.FileLinesList[StartPos[0]][Offset] not in ('\r', '\n'): + self.Profile.FileLinesList[StartPos[0]][Offset] = Value + Offset += 1 + + Line = StartPos[0] + while Line < EndPos[0]: + Offset = 0 + while self.Profile.FileLinesList[Line][Offset] not in ('\r', '\n'): + self.Profile.FileLinesList[Line][Offset] = Value + Offset += 1 + Line += 1 + + Offset = 0 + while Offset <= EndPos[1]: + self.Profile.FileLinesList[EndPos[0]][Offset] = Value + Offset += 1 + + + ## PreprocessFile() method + # + # Preprocess file contents, replace comments with spaces. + # In the end, rewind the file buffer pointer to the beginning + # BUGBUG: No !include statement processing contained in this procedure + # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1] + # + # @param self The object pointer + # + def PreprocessFile(self): + + self.Rewind() + InComment = False + DoubleSlashComment = False + HashComment = False + # HashComment in quoted string " " is ignored. + InString = False + + while not self.__EndOfFile(): + + if self.__CurrentChar() == T_CHAR_DOUBLE_QUOTE and not InComment: + InString = not InString + # meet new line, then no longer in a comment for // and '#' + if self.__CurrentChar() == T_CHAR_LF: + self.CurrentLineNumber += 1 + self.CurrentOffsetWithinLine = 0 + if InComment and DoubleSlashComment: + InComment = False + DoubleSlashComment = False + if InComment and HashComment: + InComment = False + HashComment = False + # check for */ comment end + elif InComment and not DoubleSlashComment and not HashComment and self.__CurrentChar() == T_CHAR_STAR and self.__NextChar() == T_CHAR_SLASH: + self.__SetCurrentCharValue(T_CHAR_SPACE) + self.__GetOneChar() + self.__SetCurrentCharValue(T_CHAR_SPACE) + self.__GetOneChar() + InComment = False + # set comments to spaces + elif InComment: + self.__SetCurrentCharValue(T_CHAR_SPACE) + self.__GetOneChar() + # check for // comment + elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_SLASH and not self.__EndOfLine(): + InComment = True + DoubleSlashComment = True + # check for '#' comment + elif self.__CurrentChar() == T_CHAR_HASH and not self.__EndOfLine() and not InString: + InComment = True + HashComment = True + # check for /* comment start + elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_STAR: + self.__SetCurrentCharValue( T_CHAR_SPACE) + self.__GetOneChar() + self.__SetCurrentCharValue( T_CHAR_SPACE) + self.__GetOneChar() + InComment = True + else: + self.__GetOneChar() + + # restore from ListOfList to ListOfString + self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList] + self.Rewind() + + ## PreprocessIncludeFile() method + # + # Preprocess file contents, replace !include statements with file contents. + # In the end, rewind the file buffer pointer to the beginning + # + # @param self The object pointer + # + def PreprocessIncludeFile(self): + + while self.__GetNextToken(): + + if self.__Token == '!include': + IncludeLine = self.CurrentLineNumber + IncludeOffset = self.CurrentOffsetWithinLine - len('!include') + if not self.__GetNextToken(): + raise Warning("expected include file name", self.FileName, self.CurrentLineNumber) + IncFileName = self.__Token + if not os.path.isabs(IncFileName): + if IncFileName.startswith('$(WORKSPACE)'): + Str = IncFileName.replace('$(WORKSPACE)', os.environ.get('WORKSPACE')) + if os.path.exists(Str): + if not os.path.isabs(Str): + Str = os.path.abspath(Str) + IncFileName = Str + else: + # file is in the same dir with FDF file + FullFdf = self.FileName + if not os.path.isabs(self.FileName): + FullFdf = os.path.join(os.environ.get('WORKSPACE'), self.FileName) + + IncFileName = os.path.join(os.path.dirname(FullFdf), IncFileName) + + if not os.path.exists(os.path.normpath(IncFileName)): + raise Warning("Include file not exists", self.FileName, self.CurrentLineNumber) + + IncFileProfile = IncludeFileProfile(os.path.normpath(IncFileName)) + + CurrentLine = self.CurrentLineNumber + CurrentOffset = self.CurrentOffsetWithinLine + # list index of the insertion, note that line number is 'CurrentLine + 1' + InsertAtLine = CurrentLine + IncFileProfile.InsertStartLineNumber = InsertAtLine + 1 + # deal with remaining portions after "!include filename", if exists. + if self.__GetNextToken(): + if self.CurrentLineNumber == CurrentLine: + RemainingLine = self.__CurrentLine()[CurrentOffset:] + self.Profile.FileLinesList.insert(self.CurrentLineNumber, RemainingLine) + IncFileProfile.InsertAdjust += 1 + self.CurrentLineNumber += 1 + self.CurrentOffsetWithinLine = 0 + + for Line in IncFileProfile.FileLinesList: + self.Profile.FileLinesList.insert(InsertAtLine, Line) + self.CurrentLineNumber += 1 + InsertAtLine += 1 + + IncludeFileList.append(IncFileProfile) + + # comment out the processed include file statement + TempList = list(self.Profile.FileLinesList[IncludeLine - 1]) + TempList.insert(IncludeOffset, '#') + self.Profile.FileLinesList[IncludeLine - 1] = ''.join(TempList) + + self.Rewind() + + ## PreprocessIncludeFile() method + # + # Preprocess file contents, replace !include statements with file contents. + # In the end, rewind the file buffer pointer to the beginning + # + # @param self The object pointer + # + def PreprocessConditionalStatement(self): + # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined] + IfList = [] + while self.__GetNextToken(): + if self.__Token == 'DEFINE': + DefineLine = self.CurrentLineNumber - 1 + DefineOffset = self.CurrentOffsetWithinLine - len('DEFINE') + if not self.__GetNextToken(): + raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber) + Macro = self.__Token + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected value", self.FileName, self.CurrentLineNumber) + + if self.__GetStringData(): + pass + Value = self.__Token + if not Macro in InputMacroDict: + FileLineTuple = GetRealFileLine(self.FileName, DefineLine + 1) + MacProfile = MacroProfile(FileLineTuple[0], FileLineTuple[1]) + MacProfile.MacroName = Macro + MacProfile.MacroValue = Value + AllMacroList.append(MacProfile) + self.__WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + + elif self.__Token in ('!ifdef', '!ifndef', '!if'): + IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token)) + IfList.append([IfStartPos, None, None]) + CondLabel = self.__Token + + if not self.__GetNextToken(): + raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber) + MacroName = self.__Token + NotFlag = False + if MacroName.startswith('!'): + NotFlag = True + MacroName = MacroName[1:] + + NotDefineFlag = False + if CondLabel == '!ifndef': + NotDefineFlag = True + if CondLabel == '!ifdef' or CondLabel == '!ifndef': + if NotFlag: + raise Warning("'NOT' operation not allowed for Macro name", self.FileName, self.CurrentLineNumber) + + if CondLabel == '!if': + + if not self.__GetNextOp(): + raise Warning("expected !endif", self.FileName, self.CurrentLineNumber) + + if self.__Token in ('!=', '==', '>', '<', '>=', '<='): + Op = self.__Token + if not self.__GetNextToken(): + raise Warning("expected value", self.FileName, self.CurrentLineNumber) + if self.__GetStringData(): + pass + MacroValue = self.__Token + ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, Op, MacroValue) + if NotFlag: + ConditionSatisfied = not ConditionSatisfied + BranchDetermined = ConditionSatisfied + else: + self.CurrentOffsetWithinLine -= len(self.__Token) + ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, None, 'Bool') + if NotFlag: + ConditionSatisfied = not ConditionSatisfied + BranchDetermined = ConditionSatisfied + IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined] + if ConditionSatisfied: + self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + + else: + ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1) + if NotDefineFlag: + ConditionSatisfied = not ConditionSatisfied + BranchDetermined = ConditionSatisfied + IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined] + if ConditionSatisfied: + self.__WipeOffArea.append((IfStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + + elif self.__Token in ('!elseif', '!else'): + ElseStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token)) + if len(IfList) <= 0: + raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber) + if IfList[-1][1]: + IfList[-1] = [ElseStartPos, False, True] + self.__WipeOffArea.append((ElseStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + else: + self.__WipeOffArea.append((IfList[-1][0], ElseStartPos)) + IfList[-1] = [ElseStartPos, True, IfList[-1][2]] + if self.__Token == '!elseif': + if not self.__GetNextToken(): + raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber) + MacroName = self.__Token + NotFlag = False + if MacroName.startswith('!'): + NotFlag = True + MacroName = MacroName[1:] + + if not self.__GetNextOp(): + raise Warning("expected !endif", self.FileName, self.CurrentLineNumber) + + if self.__Token in ('!=', '==', '>', '<', '>=', '<='): + Op = self.__Token + if not self.__GetNextToken(): + raise Warning("expected value", self.FileName, self.CurrentLineNumber) + if self.__GetStringData(): + pass + MacroValue = self.__Token + ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, Op, MacroValue) + if NotFlag: + ConditionSatisfied = not ConditionSatisfied + + else: + self.CurrentOffsetWithinLine -= len(self.__Token) + ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, None, 'Bool') + if NotFlag: + ConditionSatisfied = not ConditionSatisfied + + IfList[-1] = [IfList[-1][0], ConditionSatisfied, IfList[-1][2]] + + if IfList[-1][1]: + if IfList[-1][2]: + IfList[-1][1] = False + else: + IfList[-1][2] = True + self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + + + elif self.__Token == '!endif': + if IfList[-1][1]: + self.__WipeOffArea.append(((self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len('!endif')), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + else: + self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + + IfList.pop() + + + if len(IfList) > 0: + raise Warning("Missing !endif", self.FileName, self.CurrentLineNumber) + self.Rewind() + + def __EvaluateConditional(self, Name, Line, Op = None, Value = None): + + FileLineTuple = GetRealFileLine(self.FileName, Line) + if Name in InputMacroDict: + MacroValue = InputMacroDict[Name] + if Op == None: + if Value == 'Bool' and MacroValue == None or MacroValue.upper() == 'FALSE': + return False + return True + elif Op == '!=': + if Value != MacroValue: + return True + else: + return False + elif Op == '==': + if Value == MacroValue: + return True + else: + return False + else: + if (self.__IsHex(Value) or Value.isdigit()) and (self.__IsHex(MacroValue) or (MacroValue != None and MacroValue.isdigit())): + InputVal = long(Value, 0) + MacroVal = long(MacroValue, 0) + if Op == '>': + if MacroVal > InputVal: + return True + else: + return False + elif Op == '>=': + if MacroVal >= InputVal: + return True + else: + return False + elif Op == '<': + if MacroVal < InputVal: + return True + else: + return False + elif Op == '<=': + if MacroVal <= InputVal: + return True + else: + return False + else: + return False + else: + raise Warning("Value %s is not a number", self.FileName, Line) + + for Profile in AllMacroList: + if Profile.FileName == FileLineTuple[0] and Profile.MacroName == Name and Profile.DefinedAtLine <= FileLineTuple[1]: + if Op == None: + if Value == 'Bool' and Profile.MacroValue == None or Profile.MacroValue.upper() == 'FALSE': + return False + return True + elif Op == '!=': + if Value != Profile.MacroValue: + return True + else: + return False + elif Op == '==': + if Value == Profile.MacroValue: + return True + else: + return False + else: + if (self.__IsHex(Value) or Value.isdigit()) and (self.__IsHex(Profile.MacroValue) or (Profile.MacroValue != None and Profile.MacroValue.isdigit())): + InputVal = long(Value, 0) + MacroVal = long(Profile.MacroValue, 0) + if Op == '>': + if MacroVal > InputVal: + return True + else: + return False + elif Op == '>=': + if MacroVal >= InputVal: + return True + else: + return False + elif Op == '<': + if MacroVal < InputVal: + return True + else: + return False + elif Op == '<=': + if MacroVal <= InputVal: + return True + else: + return False + else: + return False + else: + raise Warning("Value %s is not a number", self.FileName, Line) + + return False + + ## __IsToken() method + # + # Check whether input string is found from current char position along + # If found, the string value is put into self.__Token + # + # @param self The object pointer + # @param String The string to search + # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive + # @retval True Successfully find string, file buffer pointer moved forward + # @retval False Not able to find string, file buffer pointer not changed + # + def __IsToken(self, String, IgnoreCase = False): + self.__SkipWhiteSpace() + + # Only consider the same line, no multi-line token allowed + StartPos = self.CurrentOffsetWithinLine + index = -1 + if IgnoreCase: + index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper()) + else: + index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String) + if index == 0: + self.CurrentOffsetWithinLine += len(String) + self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine] + return True + return False + + ## __IsKeyword() method + # + # Check whether input keyword is found from current char position along, whole word only! + # If found, the string value is put into self.__Token + # + # @param self The object pointer + # @param Keyword The string to search + # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive + # @retval True Successfully find string, file buffer pointer moved forward + # @retval False Not able to find string, file buffer pointer not changed + # + def __IsKeyword(self, KeyWord, IgnoreCase = False): + self.__SkipWhiteSpace() + + # Only consider the same line, no multi-line token allowed + StartPos = self.CurrentOffsetWithinLine + index = -1 + if IgnoreCase: + index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(KeyWord.upper()) + else: + index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(KeyWord) + if index == 0: + followingChar = self.__CurrentLine()[self.CurrentOffsetWithinLine + len(KeyWord)] + if not str(followingChar).isspace() and followingChar not in SEPERATOR_TUPLE: + return False + self.CurrentOffsetWithinLine += len(KeyWord) + self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine] + return True + return False + + ## __GetNextWord() method + # + # Get next C name from file lines + # If found, the string value is put into self.__Token + # + # @param self The object pointer + # @retval True Successfully find a C name string, file buffer pointer moved forward + # @retval False Not able to find a C name string, file buffer pointer not changed + # + def __GetNextWord(self): + self.__SkipWhiteSpace() + if self.__EndOfFile(): + return False + + TempChar = self.__CurrentChar() + StartPos = self.CurrentOffsetWithinLine + if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_': + self.__GetOneChar() + while not self.__EndOfLine(): + TempChar = self.__CurrentChar() + if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \ + or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-': + self.__GetOneChar() + + else: + break + + self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine] + return True + + return False + + ## __GetNextToken() method + # + # Get next token unit before a seperator + # If found, the string value is put into self.__Token + # + # @param self The object pointer + # @retval True Successfully find a token unit, file buffer pointer moved forward + # @retval False Not able to find a token unit, file buffer pointer not changed + # + def __GetNextToken(self): + # Skip leading spaces, if exist. + self.__SkipWhiteSpace() + if self.__EndOfFile(): + return False + # Record the token start position, the position of the first non-space char. + StartPos = self.CurrentOffsetWithinLine + StartLine = self.CurrentLineNumber + while not self.__EndOfLine(): + TempChar = self.__CurrentChar() + # Try to find the end char that is not a space and not in seperator tuple. + # That is, when we got a space or any char in the tuple, we got the end of token. + if not str(TempChar).isspace() and TempChar not in SEPERATOR_TUPLE: + self.__GetOneChar() + # if we happen to meet a seperator as the first char, we must proceed to get it. + # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens. + elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE: + self.__GetOneChar() + break + else: + break +# else: +# return False + + EndPos = self.CurrentOffsetWithinLine + if self.CurrentLineNumber != StartLine: + EndPos = len(self.Profile.FileLinesList[StartLine-1]) + self.__Token = self.Profile.FileLinesList[StartLine-1][StartPos : EndPos] + if StartPos != self.CurrentOffsetWithinLine: + return True + else: + return False + + def __GetNextOp(self): + # Skip leading spaces, if exist. + self.__SkipWhiteSpace() + if self.__EndOfFile(): + return False + # Record the token start position, the position of the first non-space char. + StartPos = self.CurrentOffsetWithinLine + while not self.__EndOfLine(): + TempChar = self.__CurrentChar() + # Try to find the end char that is not a space + if not str(TempChar).isspace(): + self.__GetOneChar() + else: + break + else: + return False + + if StartPos != self.CurrentOffsetWithinLine: + self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine] + return True + else: + return False + ## __GetNextGuid() method + # + # Get next token unit before a seperator + # If found, the GUID string is put into self.__Token + # + # @param self The object pointer + # @retval True Successfully find a registry format GUID, file buffer pointer moved forward + # @retval False Not able to find a registry format GUID, file buffer pointer not changed + # + def __GetNextGuid(self): + + if not self.__GetNextToken(): + return False + p = re.compile('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}') + if p.match(self.__Token) != None: + return True + else: + self.__UndoToken() + return False + + ## __UndoToken() method + # + # Go back one token unit in file buffer + # + # @param self The object pointer + # + def __UndoToken(self): + self.__UndoOneChar() + while self.__CurrentChar().isspace(): + if not self.__UndoOneChar(): + self.__GetOneChar() + return + + + StartPos = self.CurrentOffsetWithinLine + CurrentLine = self.CurrentLineNumber + while CurrentLine == self.CurrentLineNumber: + + TempChar = self.__CurrentChar() + # Try to find the end char that is not a space and not in seperator tuple. + # That is, when we got a space or any char in the tuple, we got the end of token. + if not str(TempChar).isspace() and not TempChar in SEPERATOR_TUPLE: + if not self.__UndoOneChar(): + break + # if we happen to meet a seperator as the first char, we must proceed to get it. + # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens. + elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE: + return + else: + break + + self.__GetOneChar() + + ## __HexDigit() method + # + # Whether char input is a Hex data bit + # + # @param self The object pointer + # @param TempChar The char to test + # @retval True The char is a Hex data bit + # @retval False The char is NOT a Hex data bit + # + def __HexDigit(self, TempChar): + if (TempChar >= 'a' and TempChar <= 'f') or (TempChar >= 'A' and TempChar <= 'F') \ + or (TempChar >= '0' and TempChar <= '9'): + return True + else: + return False + + def __IsHex(self, HexStr): + if not HexStr.upper().startswith("0X"): + return False + if len(self.__Token) <= 2: + return False + charList = [c for c in HexStr[2 : ] if not self.__HexDigit( c)] + if len(charList) == 0: + return True + else: + return False + ## __GetNextHexNumber() method + # + # Get next HEX data before a seperator + # If found, the HEX data is put into self.__Token + # + # @param self The object pointer + # @retval True Successfully find a HEX data, file buffer pointer moved forward + # @retval False Not able to find a HEX data, file buffer pointer not changed + # + def __GetNextHexNumber(self): + if not self.__GetNextToken(): + return False + if self.__IsHex(self.__Token): + return True + else: + self.__UndoToken() + return False + + ## __GetNextDecimalNumber() method + # + # Get next decimal data before a seperator + # If found, the decimal data is put into self.__Token + # + # @param self The object pointer + # @retval True Successfully find a decimal data, file buffer pointer moved forward + # @retval False Not able to find a decimal data, file buffer pointer not changed + # + def __GetNextDecimalNumber(self): + if not self.__GetNextToken(): + return False + if self.__Token.isdigit(): + return True + else: + self.__UndoToken() + return False + + ## __GetNextPcdName() method + # + # Get next PCD token space C name and PCD C name pair before a seperator + # If found, the decimal data is put into self.__Token + # + # @param self The object pointer + # @retval Tuple PCD C name and PCD token space C name pair + # + def __GetNextPcdName(self): + if not self.__GetNextWord(): + raise Warning("expected format of .", self.FileName, self.CurrentLineNumber) + pcdTokenSpaceCName = self.__Token + + if not self.__IsToken( "."): + raise Warning("expected format of .", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextWord(): + raise Warning("expected format of .", self.FileName, self.CurrentLineNumber) + pcdCName = self.__Token + + return (pcdCName, pcdTokenSpaceCName) + + ## __GetStringData() method + # + # Get string contents quoted in "" + # If found, the decimal data is put into self.__Token + # + # @param self The object pointer + # @retval True Successfully find a string data, file buffer pointer moved forward + # @retval False Not able to find a string data, file buffer pointer not changed + # + def __GetStringData(self): + if self.__Token.startswith("\"") or self.__Token.startswith("L\""): + self.__UndoToken() + self.__SkipToToken("\"") + currentLineNumber = self.CurrentLineNumber + + if not self.__SkipToToken("\""): + raise Warning("Missing Quote \" for String", self.FileName, self.CurrentLineNumber) + if currentLineNumber != self.CurrentLineNumber: + raise Warning("Missing Quote \" for String", self.FileName, self.CurrentLineNumber) + self.__Token = self.__SkippedChars.rstrip('\"') + return True + + elif self.__Token.startswith("\'") or self.__Token.startswith("L\'"): + self.__UndoToken() + self.__SkipToToken("\'") + currentLineNumber = self.CurrentLineNumber + + if not self.__SkipToToken("\'"): + raise Warning("Missing Quote \' for String", self.FileName, self.CurrentLineNumber) + if currentLineNumber != self.CurrentLineNumber: + raise Warning("Missing Quote \' for String", self.FileName, self.CurrentLineNumber) + self.__Token = self.__SkippedChars.rstrip('\'') + return True + + else: + return False + + ## __SkipToToken() method + # + # Search forward in file buffer for the string + # The skipped chars are put into self.__SkippedChars + # + # @param self The object pointer + # @param String The string to search + # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive + # @retval True Successfully find the string, file buffer pointer moved forward + # @retval False Not able to find the string, file buffer pointer not changed + # + def __SkipToToken(self, String, IgnoreCase = False): + StartPos = self.GetFileBufferPos() + + self.__SkippedChars = "" + while not self.__EndOfFile(): + index = -1 + if IgnoreCase: + index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper()) + else: + index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String) + if index == 0: + self.CurrentOffsetWithinLine += len(String) + self.__SkippedChars += String + return True + self.__SkippedChars += str(self.__CurrentChar()) + self.__GetOneChar() + + self.SetFileBufferPos( StartPos) + self.__SkippedChars = "" + return False + + ## GetFileBufferPos() method + # + # Return the tuple of current line and offset within the line + # + # @param self The object pointer + # @retval Tuple Line number and offset pair + # + def GetFileBufferPos(self): + return (self.CurrentLineNumber, self.CurrentOffsetWithinLine) + + ## SetFileBufferPos() method + # + # Restore the file buffer position + # + # @param self The object pointer + # @param Pos The new file buffer position + # + def SetFileBufferPos(self, Pos): + (self.CurrentLineNumber, self.CurrentOffsetWithinLine) = Pos + + ## ParseFile() method + # + # Parse the file profile buffer to extract fd, fv ... information + # Exception will be raised if syntax error found + # + # @param self The object pointer + # + def ParseFile(self): + + try: + self.__StringToList() + self.PreprocessFile() + self.PreprocessIncludeFile() + self.__StringToList() + self.PreprocessFile() + self.PreprocessConditionalStatement() + self.__StringToList() + for Pos in self.__WipeOffArea: + self.__ReplaceFragment(Pos[0], Pos[1]) + self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList] + + while self.__GetDefines(): + pass + + Index = 0 + while Index < len(self.Profile.FileLinesList): + FileLineTuple = GetRealFileLine(self.FileName, Index + 1) + self.Profile.FileLinesList[Index] = self.__ReplaceMacros(self.Profile.FileLinesList[Index], FileLineTuple[0], FileLineTuple[1]) + Index += 1 + + while self.__GetFd(): + pass + + while self.__GetFv(): + pass + + while self.__GetCapsule(): + pass + + while self.__GetVtf(): + pass + + while self.__GetRule(): + pass + + while self.__GetOptionRom(): + pass + + except Warning, X: + self.__UndoToken() + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + #'\n\tGot Token: \"%s\" from File %s\n' % (self.__Token, FileLineTuple[0]) + \ + X.Message += ' near line %d, column %d: %s' \ + % (FileLineTuple[1], self.CurrentOffsetWithinLine + 1, self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :].rstrip('\n').rstrip('\r')) + raise + + ## __GetDefines() method + # + # Get Defines section contents and store its data into AllMacrosList + # + # @param self The object pointer + # @retval True Successfully find a Defines + # @retval False Not able to find a Defines + # + def __GetDefines(self): + + if not self.__GetNextToken(): + return False + + S = self.__Token.upper() + if S.startswith("[") and not S.startswith("[DEFINES"): + if not S.startswith("[FD.") and not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \ + and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."): + raise Warning("Unknown section or section appear sequence error (The correct sequence should be [DEFINES], [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber) + self.__UndoToken() + return False + + self.__UndoToken() + if not self.__IsToken("[DEFINES", True): + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ + # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) + raise Warning("expected [DEFINES", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "]"): + raise Warning("expected ']'", self.FileName, self.CurrentLineNumber) + + while self.__GetNextWord(): + Macro = self.__Token + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken() or self.__Token.startswith('['): + raise Warning("expected MACRO value", self.FileName, self.CurrentLineNumber) + Value = self.__Token + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + MacProfile = MacroProfile(FileLineTuple[0], FileLineTuple[1]) + MacProfile.MacroName = Macro + MacProfile.MacroValue = Value + AllMacroList.append(MacProfile) + + return False + + ## __GetFd() method + # + # Get FD section contents and store its data into FD dictionary of self.Profile + # + # @param self The object pointer + # @retval True Successfully find a FD + # @retval False Not able to find a FD + # + def __GetFd(self): + + if not self.__GetNextToken(): + return False + + S = self.__Token.upper() + if S.startswith("[") and not S.startswith("[FD."): + if not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \ + and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."): + raise Warning("Unknown section", self.FileName, self.CurrentLineNumber) + self.__UndoToken() + return False + + self.__UndoToken() + if not self.__IsToken("[FD.", True): + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ + # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) + raise Warning("expected [FD.]", self.FileName, self.CurrentLineNumber) + + FdName = self.__GetUiName() + self.CurrentFdName = FdName.upper() + + if not self.__IsToken( "]"): + raise Warning("expected ']'", self.FileName, self.CurrentLineNumber) + + FdObj = Fd.FD() + FdObj.FdUiName = self.CurrentFdName + self.Profile.FdDict[self.CurrentFdName] = FdObj + Status = self.__GetCreateFile(FdObj) + if not Status: + raise Warning("FD name error", self.FileName, self.CurrentLineNumber) + + if not self.__GetTokenStatements(FdObj): + return False + + self.__GetDefineStatements(FdObj) + + self.__GetSetStatements(FdObj) + + if not self.__GetRegionLayout(FdObj): + raise Warning("expected region layout", self.FileName, self.CurrentLineNumber) + + while self.__GetRegionLayout(FdObj): + pass + return True + + ## __GetUiName() method + # + # Return the UI name of a section + # + # @param self The object pointer + # @retval FdName UI name + # + def __GetUiName(self): + Name = "" + if self.__GetNextWord(): + Name = self.__Token + + return Name + + ## __GetCreateFile() method + # + # Return the output file name of object + # + # @param self The object pointer + # @param Obj object whose data will be stored in file + # @retval FdName UI name + # + def __GetCreateFile(self, Obj): + + if self.__IsKeyword( "CREATE_FILE"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected file name", self.FileName, self.CurrentLineNumber) + + FileName = self.__Token + Obj.CreateFileName = FileName + + return True + + ## __GetTokenStatements() method + # + # Get token statements + # + # @param self The object pointer + # @param Obj for whom token statement is got + # @retval True Successfully find a token statement + # @retval False Not able to find a token statement + # + def __GetTokenStatements(self, Obj): + if not self.__IsKeyword( "BaseAddress"): + raise Warning("BaseAddress missing", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextHexNumber(): + raise Warning("expected Hex base address", self.FileName, self.CurrentLineNumber) + + Obj.BaseAddress = self.__Token + + if self.__IsToken( "|"): + pcdPair = self.__GetNextPcdName() + Obj.BaseAddressPcd = pcdPair + self.Profile.PcdDict[pcdPair] = Obj.BaseAddress + + if not self.__IsKeyword( "Size"): + raise Warning("Size missing", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextHexNumber(): + raise Warning("expected Hex size", self.FileName, self.CurrentLineNumber) + + + Size = self.__Token + if self.__IsToken( "|"): + pcdPair = self.__GetNextPcdName() + Obj.SizePcd = pcdPair + self.Profile.PcdDict[pcdPair] = Size + Obj.Size = long(Size, 0) + + if not self.__IsKeyword( "ErasePolarity"): + raise Warning("ErasePolarity missing", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Erase Polarity", self.FileName, self.CurrentLineNumber) + + if self.__Token != "1" and self.__Token != "0": + raise Warning("expected 1 or 0 Erase Polarity", self.FileName, self.CurrentLineNumber) + + Obj.ErasePolarity = self.__Token + + Status = self.__GetBlockStatements(Obj) + return Status + + ## __GetAddressStatements() method + # + # Get address statements + # + # @param self The object pointer + # @param Obj for whom address statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetAddressStatements(self, Obj): + + if self.__IsKeyword("BsBaseAddress"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber(): + raise Warning("expected address", self.FileName, self.CurrentLineNumber) + + BsAddress = long(self.__Token, 0) + Obj.BsBaseAddress = BsAddress + + if self.__IsKeyword("RtBaseAddress"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber(): + raise Warning("expected address", self.FileName, self.CurrentLineNumber) + + RtAddress = long(self.__Token, 0) + Obj.RtBaseAddress = RtAddress + + ## __GetBlockStatements() method + # + # Get block statements + # + # @param self The object pointer + # @param Obj for whom block statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetBlockStatements(self, Obj): + + if not self.__GetBlockStatement(Obj): + raise Warning("expected block statement", self.FileName, self.CurrentLineNumber) + + while self.__GetBlockStatement(Obj): + pass + return True + + ## __GetBlockStatement() method + # + # Get block statement + # + # @param self The object pointer + # @param Obj for whom block statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetBlockStatement(self, Obj): + if not self.__IsKeyword( "BlockSize"): + return False + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber(): + raise Warning("expected Hex block size", self.FileName, self.CurrentLineNumber) + + BlockSize = self.__Token + BlockSizePcd = None + if self.__IsToken( "|"): + PcdPair = self.__GetNextPcdName() + BlockSizePcd = PcdPair + self.Profile.PcdDict[PcdPair] = BlockSize + BlockSize = long(self.__Token, 0) + + BlockNumber = None + if self.__IsKeyword( "NumBlocks"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber(): + raise Warning("expected block numbers", self.FileName, self.CurrentLineNumber) + + BlockNumber = long(self.__Token, 0) + + Obj.BlockSizeList.append((BlockSize, BlockNumber, BlockSizePcd)) + return True + + ## __GetDefineStatements() method + # + # Get define statements + # + # @param self The object pointer + # @param Obj for whom define statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetDefineStatements(self, Obj): + while self.__GetDefineStatement( Obj): + pass + + ## __GetDefineStatement() method + # + # Get define statement + # + # @param self The object pointer + # @param Obj for whom define statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetDefineStatement(self, Obj): + if self.__IsKeyword("DEFINE"): + self.__GetNextToken() + Macro = self.__Token + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected value", self.FileName, self.CurrentLineNumber) + + Value = self.__Token + Macro = '$(' + Macro + ')' + Obj.DefineVarDict[Macro] = Value + return True + + return False + + ## __GetSetStatements() method + # + # Get set statements + # + # @param self The object pointer + # @param Obj for whom set statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetSetStatements(self, Obj): + while self.__GetSetStatement(Obj): + pass + + ## __GetSetStatement() method + # + # Get set statement + # + # @param self The object pointer + # @param Obj for whom set statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetSetStatement(self, Obj): + if self.__IsKeyword("SET"): + PcdPair = self.__GetNextPcdName() + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected value", self.FileName, self.CurrentLineNumber) + + Value = self.__Token + if Value.startswith("{"): + # deal with value with {} + if not self.__SkipToToken( "}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + Value += self.__SkippedChars + + Obj.SetVarDict[PcdPair] = Value + self.Profile.PcdDict[PcdPair] = Value + return True + + return False + + ## __GetRegionLayout() method + # + # Get region layout for FD + # + # @param self The object pointer + # @param Fd for whom region is got + # @retval True Successfully find + # @retval False Not able to find + # + def __GetRegionLayout(self, Fd): + if not self.__GetNextHexNumber(): + return False + + RegionObj = Region.Region() + RegionObj.Offset = long(self.__Token, 0) + Fd.RegionList.append(RegionObj) + + if not self.__IsToken( "|"): + raise Warning("expected '|'", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextHexNumber(): + raise Warning("expected Region Size", self.FileName, self.CurrentLineNumber) + RegionObj.Size = long(self.__Token, 0) + + if not self.__GetNextWord(): + return True + + if not self.__Token in ("SET", "FV", "FILE", "DATA"): + self.__UndoToken() + RegionObj.PcdOffset = self.__GetNextPcdName() + self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + long(Fd.BaseAddress, 0)) + if self.__IsToken( "|"): + RegionObj.PcdSize = self.__GetNextPcdName() + self.Profile.PcdDict[RegionObj.PcdSize] = "0x%08X" % RegionObj.Size + + if not self.__GetNextWord(): + return True + + if self.__Token == "SET": + self.__UndoToken() + self.__GetSetStatements( RegionObj) + if not self.__GetNextWord(): + return True + + if self.__Token == "FV": + self.__UndoToken() + self.__GetRegionFvType( RegionObj) + + elif self.__Token == "FILE": + self.__UndoToken() + self.__GetRegionFileType( RegionObj) + + else: + self.__UndoToken() + self.__GetRegionDataType( RegionObj) + + return True + + ## __GetRegionFvType() method + # + # Get region fv data for region + # + # @param self The object pointer + # @param RegionObj for whom region data is got + # + def __GetRegionFvType(self, RegionObj): + + if not self.__IsKeyword( "FV"): + raise Warning("expected Keyword 'FV'", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected FV name", self.FileName, self.CurrentLineNumber) + + RegionObj.RegionType = "FV" + RegionObj.RegionDataList.append(self.__Token) + + while self.__IsKeyword( "FV"): + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected FV name", self.FileName, self.CurrentLineNumber) + + RegionObj.RegionDataList.append(self.__Token) + + ## __GetRegionFileType() method + # + # Get region file data for region + # + # @param self The object pointer + # @param RegionObj for whom region data is got + # + def __GetRegionFileType(self, RegionObj): + + if not self.__IsKeyword( "FILE"): + raise Warning("expected Keyword 'FILE'", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected File name", self.FileName, self.CurrentLineNumber) + + RegionObj.RegionType = "FILE" + RegionObj.RegionDataList.append( self.__Token) + + while self.__IsKeyword( "FILE"): + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected FILE name", self.FileName, self.CurrentLineNumber) + + RegionObj.RegionDataList.append(self.__Token) + + ## __GetRegionDataType() method + # + # Get region array data for region + # + # @param self The object pointer + # @param RegionObj for whom region data is got + # + def __GetRegionDataType(self, RegionObj): + + if not self.__IsKeyword( "DATA"): + raise Warning("expected Region Data type", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "{"): + raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextHexNumber(): + raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber) + + if len(self.__Token) > 4: + raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber) + + DataString = self.__Token + DataString += "," + + while self.__IsToken(","): + if not self.__GetNextHexNumber(): + raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber) + if len(self.__Token) > 4: + raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber) + DataString += self.__Token + DataString += "," + + if not self.__IsToken( "}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + + DataString = DataString.rstrip(",") + RegionObj.RegionType = "DATA" + RegionObj.RegionDataList.append( DataString) + + while self.__IsKeyword( "DATA"): + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken( "{"): + raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextHexNumber(): + raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber) + + if len(self.__Token) > 4: + raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber) + + DataString = self.__Token + DataString += "," + + while self.__IsToken(","): + self.__GetNextHexNumber() + if len(self.__Token) > 4: + raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber) + DataString += self.__Token + DataString += "," + + if not self.__IsToken( "}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + + DataString = DataString.rstrip(",") + RegionObj.RegionDataList.append( DataString) + + ## __GetFv() method + # + # Get FV section contents and store its data into FV dictionary of self.Profile + # + # @param self The object pointer + # @retval True Successfully find a FV + # @retval False Not able to find a FV + # + def __GetFv(self): + if not self.__GetNextToken(): + return False + + S = self.__Token.upper() + if S.startswith("[") and not S.startswith("[FV."): + if not S.startswith("[CAPSULE.") \ + and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."): + raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber) + self.__UndoToken() + return False + + self.__UndoToken() + if not self.__IsToken("[FV.", True): + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ + # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) + raise Warning("Unknown Keyword '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + + FvName = self.__GetUiName() + self.CurrentFvName = FvName.upper() + + if not self.__IsToken( "]"): + raise Warning("expected ']'", self.FileName, self.CurrentLineNumber) + + FvObj = Fv.FV() + FvObj.UiFvName = self.CurrentFvName + self.Profile.FvDict[self.CurrentFvName] = FvObj + + Status = self.__GetCreateFile(FvObj) + if not Status: + raise Warning("FV name error", self.FileName, self.CurrentLineNumber) + + self.__GetDefineStatements(FvObj) + + self.__GetAddressStatements(FvObj) + + self.__GetBlockStatement(FvObj) + + self.__GetSetStatements(FvObj) + + self.__GetFvAlignment(FvObj) + + self.__GetFvAttributes(FvObj) + + self.__GetFvNameGuid(FvObj) + + self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy()) + self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy()) + + while True: + isInf = self.__GetInfStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy()) + isFile = self.__GetFileStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy()) + if not isInf and not isFile: + break + + return True + + ## __GetFvAlignment() method + # + # Get alignment for FV + # + # @param self The object pointer + # @param Obj for whom alignment is got + # @retval True Successfully find a alignment statement + # @retval False Not able to find a alignment statement + # + def __GetFvAlignment(self, Obj): + + if not self.__IsKeyword( "FvAlignment"): + return False + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber) + + if self.__Token.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \ + "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \ + "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \ + "1G", "2G"): + raise Warning("Unknown alignment value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + Obj.FvAlignment = self.__Token + return True + + ## __GetFvAttributes() method + # + # Get attributes for FV + # + # @param self The object pointer + # @param Obj for whom attribute is got + # @retval None + # + def __GetFvAttributes(self, FvObj): + + while self.__GetNextWord(): + name = self.__Token + if name not in ("ERASE_POLARITY", "MEMORY_MAPPED", \ + "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \ + "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \ + "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \ + "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \ + "WRITE_POLICY_RELIABLE"): + self.__UndoToken() + return + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"): + raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber) + + FvObj.FvAttributeDict[name] = self.__Token + + return + + ## __GetFvNameGuid() method + # + # Get FV GUID for FV + # + # @param self The object pointer + # @param Obj for whom GUID is got + # @retval None + # + def __GetFvNameGuid(self, FvObj): + + if not self.__IsKeyword( "FvNameGuid"): + return + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextGuid(): + raise Warning("expected FV GUID value", self.FileName, self.CurrentLineNumber) + + FvObj.FvNameGuid = self.__Token + + return + + ## __GetAprioriSection() method + # + # Get token statements + # + # @param self The object pointer + # @param FvObj for whom apriori is got + # @param MacroDict dictionary used to replace macro + # @retval True Successfully find apriori statement + # @retval False Not able to find apriori statement + # + def __GetAprioriSection(self, FvObj, MacroDict = {}): + + if not self.__IsKeyword( "APRIORI"): + return False + + if not self.__IsKeyword("PEI") and not self.__IsKeyword("DXE"): + raise Warning("expected Apriori file type", self.FileName, self.CurrentLineNumber) + AprType = self.__Token + + if not self.__IsToken( "{"): + raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) + + AprSectionObj = AprioriSection.AprioriSection() + AprSectionObj.AprioriType = AprType + + self.__GetDefineStatements(AprSectionObj) + MacroDict.update(AprSectionObj.DefineVarDict) + + while True: + IsInf = self.__GetInfStatement( AprSectionObj, MacroDict = MacroDict) + IsFile = self.__GetFileStatement( AprSectionObj) + if not IsInf and not IsFile: + break + + if not self.__IsToken( "}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + + FvObj.AprioriSectionList.append(AprSectionObj) + return True + + ## __GetInfStatement() method + # + # Get INF statements + # + # @param self The object pointer + # @param Obj for whom inf statement is got + # @param MacroDict dictionary used to replace macro + # @retval True Successfully find inf statement + # @retval False Not able to find inf statement + # + def __GetInfStatement(self, Obj, ForCapsule = False, MacroDict = {}): + + if not self.__IsKeyword( "INF"): + return False + + ffsInf = FfsInfStatement.FfsInfStatement() + self.__GetInfOptions( ffsInf) + + if not self.__GetNextToken(): + raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber) + ffsInf.InfFileName = self.__Token + +# if ffsInf.InfFileName.find('$') >= 0: +# ffsInf.InfFileName = GenFdsGlobalVariable.GenFdsGlobalVariable.MacroExtend(ffsInf.InfFileName, MacroDict) + + if not ffsInf.InfFileName in self.Profile.InfList: + self.Profile.InfList.append(ffsInf.InfFileName) + + if self.__IsToken('|'): + if self.__IsKeyword('RELOCS_STRIPPED'): + ffsInf.KeepReloc = False + elif self.__IsKeyword('RELOCS_RETAINED'): + ffsInf.KeepReloc = True + else: + raise Warning("Unknown reloc strip flag '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + + if ForCapsule: + capsuleFfs = CapsuleData.CapsuleFfs() + capsuleFfs.Ffs = ffsInf + Obj.CapsuleDataList.append(capsuleFfs) + else: + Obj.FfsList.append(ffsInf) + return True + + ## __GetInfOptions() method + # + # Get options for INF + # + # @param self The object pointer + # @param FfsInfObj for whom option is got + # + def __GetInfOptions(self, FfsInfObj): + + if self.__IsKeyword( "RuleOverride"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected Rule name", self.FileName, self.CurrentLineNumber) + FfsInfObj.Rule = self.__Token + + if self.__IsKeyword( "VERSION"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected Version", self.FileName, self.CurrentLineNumber) + + if self.__GetStringData(): + FfsInfObj.Version = self.__Token + + if self.__IsKeyword( "UI"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected UI name", self.FileName, self.CurrentLineNumber) + + if self.__GetStringData(): + FfsInfObj.Ui = self.__Token + + if self.__IsKeyword( "USE"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected ARCH name", self.FileName, self.CurrentLineNumber) + FfsInfObj.UseArch = self.__Token + + + if self.__GetNextToken(): + p = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)') + if p.match(self.__Token): + FfsInfObj.KeyStringList.append(self.__Token) + if not self.__IsToken(","): + return + else: + self.__UndoToken() + return + + while self.__GetNextToken(): + if not p.match(self.__Token): + raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber) + FfsInfObj.KeyStringList.append(self.__Token) + + if not self.__IsToken(","): + break + + ## __GetFileStatement() method + # + # Get FILE statements + # + # @param self The object pointer + # @param Obj for whom FILE statement is got + # @param MacroDict dictionary used to replace macro + # @retval True Successfully find FILE statement + # @retval False Not able to find FILE statement + # + def __GetFileStatement(self, Obj, ForCapsule = False, MacroDict = {}): + + if not self.__IsKeyword( "FILE"): + return False + + FfsFileObj = FfsFileStatement.FileStatement() + + if not self.__GetNextWord(): + raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber) + FfsFileObj.FvFileType = self.__Token + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextGuid(): + if not self.__GetNextWord(): + raise Warning("expected File GUID", self.FileName, self.CurrentLineNumber) + if self.__Token == 'PCD': + if not self.__IsToken( "("): + raise Warning("expected '('", self.FileName, self.CurrentLineNumber) + PcdPair = self.__GetNextPcdName() + if not self.__IsToken( ")"): + raise Warning("expected ')'", self.FileName, self.CurrentLineNumber) + self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')' + + FfsFileObj.NameGuid = self.__Token + + self.__GetFilePart( FfsFileObj, MacroDict.copy()) + + if ForCapsule: + capsuleFfs = CapsuleData.CapsuleFfs() + capsuleFfs.Ffs = FfsFileObj + Obj.CapsuleDataList.append(capsuleFfs) + else: + Obj.FfsList.append(FfsFileObj) + + return True + + ## __FileCouldHaveRelocFlag() method + # + # Check whether reloc strip flag can be set for a file type. + # + # @param self The object pointer + # @param FileType The file type to check with + # @retval True This type could have relocation strip flag + # @retval False No way to have it + # + + def __FileCouldHaveRelocFlag (self, FileType): + if FileType in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'): + return True + else: + return False + + ## __SectionCouldHaveRelocFlag() method + # + # Check whether reloc strip flag can be set for a section type. + # + # @param self The object pointer + # @param SectionType The section type to check with + # @retval True This type could have relocation strip flag + # @retval False No way to have it + # + + def __SectionCouldHaveRelocFlag (self, SectionType): + if SectionType in ('TE', 'PE32'): + return True + else: + return False + + ## __GetFilePart() method + # + # Get components for FILE statement + # + # @param self The object pointer + # @param FfsFileObj for whom component is got + # @param MacroDict dictionary used to replace macro + # + def __GetFilePart(self, FfsFileObj, MacroDict = {}): + + self.__GetFileOpts( FfsFileObj) + + if not self.__IsToken("{"): +# if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'): +# if self.__FileCouldHaveRelocFlag(FfsFileObj.FvFileType): +# if self.__Token == 'RELOCS_STRIPPED': +# FfsFileObj.KeepReloc = False +# else: +# FfsFileObj.KeepReloc = True +# else: +# raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) +# +# if not self.__IsToken("{"): + raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected File name or section data", self.FileName, self.CurrentLineNumber) + + if self.__Token == "FV": + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected FV name", self.FileName, self.CurrentLineNumber) + FfsFileObj.FvName = self.__Token + + elif self.__Token == "FD": + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected FD name", self.FileName, self.CurrentLineNumber) + FfsFileObj.FdName = self.__Token + + elif self.__Token in ("DEFINE", "APRIORI", "SECTION"): + self.__UndoToken() + self.__GetSectionData( FfsFileObj, MacroDict) + else: + FfsFileObj.FileName = self.__Token + + if not self.__IsToken( "}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + + ## __GetFileOpts() method + # + # Get options for FILE statement + # + # @param self The object pointer + # @param FfsFileObj for whom options is got + # + def __GetFileOpts(self, FfsFileObj): + + if self.__GetNextToken(): + Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)') + if Pattern.match(self.__Token): + FfsFileObj.KeyStringList.append(self.__Token) + if self.__IsToken(","): + while self.__GetNextToken(): + if not Pattern.match(self.__Token): + raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber) + FfsFileObj.KeyStringList.append(self.__Token) + + if not self.__IsToken(","): + break + + else: + self.__UndoToken() + + if self.__IsKeyword( "FIXED", True): + FfsFileObj.Fixed = True + + if self.__IsKeyword( "CHECKSUM", True): + FfsFileObj.CheckSum = True + + if self.__GetAlignment(): + FfsFileObj.Alignment = self.__Token + + + + ## __GetAlignment() method + # + # Return the alignment value + # + # @param self The object pointer + # @retval True Successfully find alignment + # @retval False Not able to find alignment + # + def __GetAlignment(self): + if self.__IsKeyword( "Align", True): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber) + return True + + return False + + ## __GetFilePart() method + # + # Get section data for FILE statement + # + # @param self The object pointer + # @param FfsFileObj for whom section is got + # @param MacroDict dictionary used to replace macro + # + def __GetSectionData(self, FfsFileObj, MacroDict = {}): + Dict = {} + Dict.update(MacroDict) + + self.__GetDefineStatements(FfsFileObj) + + Dict.update(FfsFileObj.DefineVarDict) + self.__GetAprioriSection(FfsFileObj, Dict.copy()) + self.__GetAprioriSection(FfsFileObj, Dict.copy()) + + while True: + IsLeafSection = self.__GetLeafSection(FfsFileObj, Dict) + IsEncapSection = self.__GetEncapsulationSec(FfsFileObj) + if not IsLeafSection and not IsEncapSection: + break + + ## __GetLeafSection() method + # + # Get leaf section for Obj + # + # @param self The object pointer + # @param Obj for whom leaf section is got + # @param MacroDict dictionary used to replace macro + # @retval True Successfully find section statement + # @retval False Not able to find section statement + # + def __GetLeafSection(self, Obj, MacroDict = {}): + + OldPos = self.GetFileBufferPos() + + if not self.__IsKeyword( "SECTION"): + if len(Obj.SectionList) == 0: + raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber) + else: + return False + + AlignValue = None + if self.__GetAlignment(): + AlignValue = self.__Token + + BuildNum = None + if self.__IsKeyword( "BUILD_NUM"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Build number value", self.FileName, self.CurrentLineNumber) + + BuildNum = self.__Token + + if self.__IsKeyword( "VERSION"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected version", self.FileName, self.CurrentLineNumber) + VerSectionObj = VerSection.VerSection() + VerSectionObj.Alignment = AlignValue + VerSectionObj.BuildNum = BuildNum + if self.__GetStringData(): + VerSectionObj.StringData = self.__Token + else: + VerSectionObj.FileName = self.__Token + Obj.SectionList.append(VerSectionObj) + + elif self.__IsKeyword( "UI"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected UI", self.FileName, self.CurrentLineNumber) + UiSectionObj = UiSection.UiSection() + UiSectionObj.Alignment = AlignValue + if self.__GetStringData(): + UiSectionObj.StringData = self.__Token + else: + UiSectionObj.FileName = self.__Token + Obj.SectionList.append(UiSectionObj) + + elif self.__IsKeyword( "FV_IMAGE"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected FV name or FV file path", self.FileName, self.CurrentLineNumber) + + FvName = self.__Token + FvObj = None + + if self.__IsToken( "{"): + FvObj = Fv.FV() + FvObj.UiFvName = FvName.upper() + self.__GetDefineStatements(FvObj) + MacroDict.update(FvObj.DefineVarDict) + self.__GetBlockStatement(FvObj) + self.__GetSetStatements(FvObj) + self.__GetFvAlignment(FvObj) + self.__GetFvAttributes(FvObj) + self.__GetAprioriSection(FvObj, MacroDict.copy()) + self.__GetAprioriSection(FvObj, MacroDict.copy()) + + while True: + IsInf = self.__GetInfStatement(FvObj, MacroDict.copy()) + IsFile = self.__GetFileStatement(FvObj, MacroDict.copy()) + if not IsInf and not IsFile: + break + + if not self.__IsToken( "}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + + FvImageSectionObj = FvImageSection.FvImageSection() + FvImageSectionObj.Alignment = AlignValue + if FvObj != None: + FvImageSectionObj.Fv = FvObj + FvImageSectionObj.FvName = None + else: + FvImageSectionObj.FvName = FvName.upper() + FvImageSectionObj.FvFileName = FvName + + Obj.SectionList.append(FvImageSectionObj) + + elif self.__IsKeyword("PEI_DEPEX_EXP") or self.__IsKeyword("DXE_DEPEX_EXP") or self.__IsKeyword("SMM_DEPEX_EXP"): + DepexSectionObj = DepexSection.DepexSection() + DepexSectionObj.Alignment = AlignValue + DepexSectionObj.DepexType = self.__Token + + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__IsToken( "{"): + raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) + if not self.__SkipToToken( "}"): + raise Warning("expected Depex expression ending '}'", self.FileName, self.CurrentLineNumber) + + DepexSectionObj.Expression = self.__SkippedChars.rstrip('}') + Obj.SectionList.append(DepexSectionObj) + + else: + + if not self.__GetNextWord(): + raise Warning("expected section type", self.FileName, self.CurrentLineNumber) + + # Encapsulation section appear, UndoToken and return + if self.__Token == "COMPRESS" or self.__Token == "GUIDED": + self.SetFileBufferPos(OldPos) + return False + + if self.__Token not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\ + "UI", "VERSION", "PEI_DEPEX", "SUBTYPE_GUID", "SMM_DEPEX"): + raise Warning("Unknown section type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + # DataSection + DataSectionObj = DataSection.DataSection() + DataSectionObj.Alignment = AlignValue + DataSectionObj.SecType = self.__Token + + if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'): + if self.__FileCouldHaveRelocFlag(Obj.FvFileType) and self.__SectionCouldHaveRelocFlag(DataSectionObj.SecType): + if self.__Token == 'RELOCS_STRIPPED': + DataSectionObj.KeepReloc = False + else: + DataSectionObj.KeepReloc = True + else: + raise Warning("File type %s, section type %s, could not have reloc strip flag%d" % (Obj.FvFileType, DataSectionObj.SecType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + + if self.__IsToken("="): + if not self.__GetNextToken(): + raise Warning("expected section file path", self.FileName, self.CurrentLineNumber) + DataSectionObj.SectFileName = self.__Token + else: + if not self.__GetCglSection(DataSectionObj): + return False + + Obj.SectionList.append(DataSectionObj) + + return True + + ## __GetCglSection() method + # + # Get compressed or GUIDed section for Obj + # + # @param self The object pointer + # @param Obj for whom leaf section is got + # @param AlignValue alignment value for complex section + # @retval True Successfully find section statement + # @retval False Not able to find section statement + # + def __GetCglSection(self, Obj, AlignValue = None): + + if self.__IsKeyword( "COMPRESS"): + type = "PI_STD" + if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"): + type = self.__Token + + if not self.__IsToken("{"): + raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) + + CompressSectionObj = CompressSection.CompressSection() + CompressSectionObj.Alignment = AlignValue + CompressSectionObj.CompType = type + # Recursive sections... + while True: + IsLeafSection = self.__GetLeafSection(CompressSectionObj) + IsEncapSection = self.__GetEncapsulationSec(CompressSectionObj) + if not IsLeafSection and not IsEncapSection: + break + + + if not self.__IsToken( "}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + Obj.SectionList.append(CompressSectionObj) + +# else: +# raise Warning("Compress type not known") + + return True + + elif self.__IsKeyword( "GUIDED"): + GuidValue = None + if self.__GetNextGuid(): + GuidValue = self.__Token + + AttribDict = self.__GetGuidAttrib() + if not self.__IsToken("{"): + raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) + GuidSectionObj = GuidSection.GuidSection() + GuidSectionObj.Alignment = AlignValue + GuidSectionObj.NameGuid = GuidValue + GuidSectionObj.SectionType = "GUIDED" + GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"] + GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"] + # Recursive sections... + while True: + IsLeafSection = self.__GetLeafSection(GuidSectionObj) + IsEncapSection = self.__GetEncapsulationSec(GuidSectionObj) + if not IsLeafSection and not IsEncapSection: + break + + if not self.__IsToken( "}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + Obj.SectionList.append(GuidSectionObj) + + return True + + return False + + ## __GetGuidAttri() method + # + # Get attributes for GUID section + # + # @param self The object pointer + # @retval AttribDict Dictionary of key-value pair of section attributes + # + def __GetGuidAttrib(self): + + AttribDict = {} + AttribDict["PROCESSING_REQUIRED"] = False + AttribDict["AUTH_STATUS_VALID"] = False + if self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID"): + AttribKey = self.__Token + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"): + raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber) + AttribDict[AttribKey] = self.__Token + + if self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID"): + AttribKey = self.__Token + + if not self.__IsToken("="): + raise Warning("expected '='") + + if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"): + raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber) + AttribDict[AttribKey] = self.__Token + + return AttribDict + + ## __GetEncapsulationSec() method + # + # Get encapsulation section for FILE + # + # @param self The object pointer + # @param FfsFile for whom section is got + # @retval True Successfully find section statement + # @retval False Not able to find section statement + # + def __GetEncapsulationSec(self, FfsFileObj): + + OldPos = self.GetFileBufferPos() + if not self.__IsKeyword( "SECTION"): + if len(FfsFileObj.SectionList) == 0: + raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber) + else: + return False + + AlignValue = None + if self.__GetAlignment(): + AlignValue = self.__Token + + if not self.__GetCglSection(FfsFileObj, AlignValue): + self.SetFileBufferPos(OldPos) + return False + else: + return True + + ## __GetCapsule() method + # + # Get capsule section contents and store its data into capsule list of self.Profile + # + # @param self The object pointer + # @retval True Successfully find a capsule + # @retval False Not able to find a capsule + # + def __GetCapsule(self): + + if not self.__GetNextToken(): + return False + + S = self.__Token.upper() + if S.startswith("[") and not S.startswith("[CAPSULE."): + if not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."): + raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber) + self.__UndoToken() + return False + + self.__UndoToken() + if not self.__IsToken("[CAPSULE.", True): + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ + # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) + raise Warning("expected [Capsule.]", self.FileName, self.CurrentLineNumber) + + CapsuleObj = Capsule.Capsule() + + CapsuleName = self.__GetUiName() + if not CapsuleName: + raise Warning("expected capsule name", self.FileName, self.CurrentLineNumber) + + CapsuleObj.UiCapsuleName = CapsuleName.upper() + + if not self.__IsToken( "]"): + raise Warning("expected ']'", self.FileName, self.CurrentLineNumber) + + if self.__IsKeyword("CREATE_FILE"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected file name", self.FileName, self.CurrentLineNumber) + + CapsuleObj.CreateFile = self.__Token + + self.__GetCapsuleStatements(CapsuleObj) + self.Profile.CapsuleList.append(CapsuleObj) + return True + + ## __GetCapsuleStatements() method + # + # Get statements for capsule + # + # @param self The object pointer + # @param Obj for whom statements are got + # + def __GetCapsuleStatements(self, Obj): + self.__GetCapsuleTokens(Obj) + self.__GetDefineStatements(Obj) + self.__GetSetStatements(Obj) + + self.__GetCapsuleData(Obj) + + ## __GetCapsuleStatements() method + # + # Get token statements for capsule + # + # @param self The object pointer + # @param Obj for whom token statements are got + # + def __GetCapsuleTokens(self, Obj): + + if not self.__IsKeyword("CAPSULE_GUID"): + raise Warning("expected 'CAPSULE_GUID'", self.FileName, self.CurrentLineNumber) + + while self.__CurrentLine().find("=") != -1: + NameValue = self.__CurrentLine().split("=") + Obj.TokensDict[NameValue[0].strip()] = NameValue[1].strip() + self.CurrentLineNumber += 1 + self.CurrentOffsetWithinLine = 0 + + ## __GetCapsuleData() method + # + # Get capsule data for capsule + # + # @param self The object pointer + # @param Obj for whom capsule data are got + # + def __GetCapsuleData(self, Obj): + + while True: + IsInf = self.__GetInfStatement(Obj, True) + IsFile = self.__GetFileStatement(Obj, True) + IsFv = self.__GetFvStatement(Obj) + if not IsInf and not IsFile and not IsFv: + break + + ## __GetFvStatement() method + # + # Get FV for capsule + # + # @param self The object pointer + # @param CapsuleObj for whom FV is got + # @retval True Successfully find a FV statement + # @retval False Not able to find a FV statement + # + def __GetFvStatement(self, CapsuleObj): + + if not self.__IsKeyword("FV"): + return False + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected FV name", self.FileName, self.CurrentLineNumber) + + CapsuleFv = CapsuleData.CapsuleFv() + CapsuleFv.FvName = self.__Token + CapsuleObj.CapsuleDataList.append(CapsuleFv) + return True + + ## __GetRule() method + # + # Get Rule section contents and store its data into rule list of self.Profile + # + # @param self The object pointer + # @retval True Successfully find a Rule + # @retval False Not able to find a Rule + # + def __GetRule(self): + + if not self.__GetNextToken(): + return False + + S = self.__Token.upper() + if S.startswith("[") and not S.startswith("[RULE."): + if not S.startswith("[OPTIONROM."): + raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber) + self.__UndoToken() + return False + self.__UndoToken() + if not self.__IsToken("[Rule.", True): + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ + # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) + raise Warning("expected [Rule.]", self.FileName, self.CurrentLineNumber) + + if not self.__SkipToToken("."): + raise Warning("expected '.'", self.FileName, self.CurrentLineNumber) + + Arch = self.__SkippedChars.rstrip(".") + if Arch.upper() not in ("IA32", "X64", "IPF", "EBC", "ARM", "COMMON"): + raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber) + + ModuleType = self.__GetModuleType() + + TemplateName = "" + if self.__IsToken("."): + if not self.__GetNextWord(): + raise Warning("expected template name", self.FileName, self.CurrentLineNumber) + TemplateName = self.__Token + + if not self.__IsToken( "]"): + raise Warning("expected ']'", self.FileName, self.CurrentLineNumber) + + RuleObj = self.__GetRuleFileStatements() + RuleObj.Arch = Arch.upper() + RuleObj.ModuleType = ModuleType + RuleObj.TemplateName = TemplateName + if TemplateName == '' : + self.Profile.RuleDict['RULE' + \ + '.' + \ + Arch.upper() + \ + '.' + \ + ModuleType.upper() ] = RuleObj + else : + self.Profile.RuleDict['RULE' + \ + '.' + \ + Arch.upper() + \ + '.' + \ + ModuleType.upper() + \ + '.' + \ + TemplateName.upper() ] = RuleObj +# self.Profile.RuleList.append(rule) + return True + + ## __GetModuleType() method + # + # Return the module type + # + # @param self The object pointer + # @retval string module type + # + def __GetModuleType(self): + + if not self.__GetNextWord(): + raise Warning("expected Module type", self.FileName, self.CurrentLineNumber) + if self.__Token.upper() not in ("SEC", "PEI_CORE", "PEIM", "DXE_CORE", \ + "DXE_DRIVER", "DXE_SAL_DRIVER", \ + "DXE_SMM_DRIVER", "DXE_RUNTIME_DRIVER", \ + "UEFI_DRIVER", "UEFI_APPLICATION", "USER_DEFINED", "DEFAULT", "BASE", \ + "SECURITY_CORE", "COMBINED_PEIM_DRIVER", "PIC_PEIM", "RELOCATABLE_PEIM", \ + "PE32_PEIM", "BS_DRIVER", "RT_DRIVER", "SAL_RT_DRIVER", "APPLICATION", "ACPITABLE", "SMM_DRIVER", "SMM_CORE"): + raise Warning("Unknown Module type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + return self.__Token + + ## __GetFileExtension() method + # + # Return the file extension + # + # @param self The object pointer + # @retval string file name extension + # + def __GetFileExtension(self): + if not self.__IsToken("."): + raise Warning("expected '.'", self.FileName, self.CurrentLineNumber) + + Ext = "" + if self.__GetNextToken(): + Pattern = re.compile(r'([a-zA-Z][a-zA-Z0-9]*)') + if Pattern.match(self.__Token): + Ext = self.__Token + return '.' + Ext + else: + raise Warning("Unknown file extension '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + + else: + raise Warning("expected file extension", self.FileName, self.CurrentLineNumber) + + ## __GetRuleFileStatement() method + # + # Get rule contents + # + # @param self The object pointer + # @retval Rule Rule object + # + def __GetRuleFileStatements(self): + + if not self.__IsKeyword("FILE"): + raise Warning("expected FILE", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextWord(): + raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber) + + Type = self.__Token.strip().upper() + if Type not in ("RAW", "FREEFORM", "SEC", "PEI_CORE", "PEIM",\ + "PEI_DXE_COMBO", "DRIVER", "DXE_CORE", "APPLICATION", "FV_IMAGE", "SMM_DXE_COMBO", "SMM", "SMM_CORE"): + raise Warning("Unknown FV type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__IsKeyword("$(NAMED_GUID)"): + if not self.__GetNextWord(): + raise Warning("expected $(NAMED_GUID)", self.FileName, self.CurrentLineNumber) + if self.__Token == 'PCD': + if not self.__IsToken( "("): + raise Warning("expected '('", self.FileName, self.CurrentLineNumber) + PcdPair = self.__GetNextPcdName() + if not self.__IsToken( ")"): + raise Warning("expected ')'", self.FileName, self.CurrentLineNumber) + self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')' + + NameGuid = self.__Token + + KeepReloc = None + if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'): + if self.__FileCouldHaveRelocFlag(Type): + if self.__Token == 'RELOCS_STRIPPED': + KeepReloc = False + else: + KeepReloc = True + else: + raise Warning("File type %s could not have reloc strip flag%d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + + KeyStringList = [] + if self.__GetNextToken(): + Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)') + if Pattern.match(self.__Token): + KeyStringList.append(self.__Token) + if self.__IsToken(","): + while self.__GetNextToken(): + if not Pattern.match(self.__Token): + raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber) + KeyStringList.append(self.__Token) + + if not self.__IsToken(","): + break + + else: + self.__UndoToken() + + + Fixed = False + if self.__IsKeyword("Fixed", True): + Fixed = True + + CheckSum = False + if self.__IsKeyword("CheckSum", True): + CheckSum = True + + AlignValue = "" + if self.__GetAlignment(): + if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): + raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + AlignValue = self.__Token + + if self.__IsToken("{"): + # Complex file rule expected + Rule = RuleComplexFile.RuleComplexFile() + Rule.FvFileType = Type + Rule.NameGuid = NameGuid + Rule.Alignment = AlignValue + Rule.CheckSum = CheckSum + Rule.Fixed = Fixed + Rule.KeyStringList = KeyStringList + if KeepReloc != None: + Rule.KeepReloc = KeepReloc + + while True: + IsEncapsulate = self.__GetRuleEncapsulationSection(Rule) + IsLeaf = self.__GetEfiSection(Rule) + if not IsEncapsulate and not IsLeaf: + break + + if not self.__IsToken("}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + + return Rule + + elif self.__IsToken("|"): + # Ext rule expected + Ext = self.__GetFileExtension() + + Rule = RuleSimpleFile.RuleSimpleFile() + + Rule.FvFileType = Type + Rule.NameGuid = NameGuid + Rule.Alignment = AlignValue + Rule.CheckSum = CheckSum + Rule.Fixed = Fixed + Rule.FileExtension = Ext + Rule.KeyStringList = KeyStringList + if KeepReloc != None: + Rule.KeepReloc = KeepReloc + + return Rule + + else: + # Simple file rule expected + if not self.__GetNextWord(): + raise Warning("expected leaf section type", self.FileName, self.CurrentLineNumber) + + SectionName = self.__Token + + if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\ + "UI", "PEI_DEPEX", "VERSION", "SUBTYPE_GUID", "SMM_DEPEX"): + raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber) + + + if self.__IsKeyword("Fixed", True): + Fixed = True + + if self.__IsKeyword("CheckSum", True): + CheckSum = True + + if self.__GetAlignment(): + if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): + raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + AlignValue = self.__Token + + if not self.__GetNextToken(): + raise Warning("expected File name", self.FileName, self.CurrentLineNumber) + + Rule = RuleSimpleFile.RuleSimpleFile() + Rule.SectionType = SectionName + Rule.FvFileType = Type + Rule.NameGuid = NameGuid + Rule.Alignment = AlignValue + Rule.CheckSum = CheckSum + Rule.Fixed = Fixed + Rule.FileName = self.__Token + Rule.KeyStringList = KeyStringList + if KeepReloc != None: + Rule.KeepReloc = KeepReloc + return Rule + + ## __GetEfiSection() method + # + # Get section list for Rule + # + # @param self The object pointer + # @param Obj for whom section is got + # @retval True Successfully find section statement + # @retval False Not able to find section statement + # + def __GetEfiSection(self, Obj): + + OldPos = self.GetFileBufferPos() + if not self.__GetNextWord(): + return False + SectionName = self.__Token + + if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\ + "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"): + self.__UndoToken() + return False + + if SectionName == "FV_IMAGE": + FvImageSectionObj = FvImageSection.FvImageSection() + if self.__IsKeyword("FV_IMAGE"): + pass + if self.__IsToken( "{"): + FvObj = Fv.FV() + self.__GetDefineStatements(FvObj) + self.__GetBlockStatement(FvObj) + self.__GetSetStatements(FvObj) + self.__GetFvAlignment(FvObj) + self.__GetFvAttributes(FvObj) + self.__GetAprioriSection(FvObj) + self.__GetAprioriSection(FvObj) + + while True: + IsInf = self.__GetInfStatement(FvObj) + IsFile = self.__GetFileStatement(FvObj) + if not IsInf and not IsFile: + break + + if not self.__IsToken( "}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + FvImageSectionObj.Fv = FvObj + FvImageSectionObj.FvName = None + + else: + if not self.__IsKeyword("FV"): + raise Warning("expected 'FV'", self.FileName, self.CurrentLineNumber) + FvImageSectionObj.FvFileType = self.__Token + + if self.__GetAlignment(): + if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): + raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + FvImageSectionObj.Alignment = self.__Token + + if self.__IsKeyword("FV"): + FvImageSectionObj.FvFileType = self.__Token + + if self.__GetAlignment(): + if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): + raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + FvImageSectionObj.Alignment = self.__Token + + if self.__IsToken('|'): + FvImageSectionObj.FvFileExtension = self.__GetFileExtension() + elif self.__GetNextToken(): + if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\ + "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"): + FvImageSectionObj.FvFileName = self.__Token + else: + self.__UndoToken() + else: + raise Warning("expected FV file name", self.FileName, self.CurrentLineNumber) + + Obj.SectionList.append(FvImageSectionObj) + return True + + EfiSectionObj = EfiSection.EfiSection() + EfiSectionObj.SectionType = SectionName + + if not self.__GetNextToken(): + raise Warning("expected file type", self.FileName, self.CurrentLineNumber) + + if self.__Token == "STRING": + if not self.__RuleSectionCouldHaveString(EfiSectionObj.SectionType): + raise Warning("%s section could NOT have string data%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + + if not self.__IsToken('='): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Quoted String", self.FileName, self.CurrentLineNumber) + + if self.__GetStringData(): + EfiSectionObj.StringData = self.__Token + + if self.__IsKeyword("BUILD_NUM"): + if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType): + raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected Build number", self.FileName, self.CurrentLineNumber) + EfiSectionObj.BuildNum = self.__Token + + else: + EfiSectionObj.FileType = self.__Token + self.__CheckRuleSectionFileType(EfiSectionObj.SectionType, EfiSectionObj.FileType) + + if self.__IsKeyword("Optional"): + if not self.__RuleSectionCouldBeOptional(EfiSectionObj.SectionType): + raise Warning("%s section could NOT be optional%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + EfiSectionObj.Optional = True + + if self.__IsKeyword("BUILD_NUM"): + if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType): + raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected Build number", self.FileName, self.CurrentLineNumber) + EfiSectionObj.BuildNum = self.__Token + + if self.__GetAlignment(): + EfiSectionObj.Alignment = self.__Token + + if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'): + if self.__SectionCouldHaveRelocFlag(EfiSectionObj.SectionType): + if self.__Token == 'RELOCS_STRIPPED': + EfiSectionObj.KeepReloc = False + else: + EfiSectionObj.KeepReloc = True + if Obj.KeepReloc != None and Obj.KeepReloc != EfiSectionObj.KeepReloc: + raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber) + else: + raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber) + + + if self.__IsToken('|'): + EfiSectionObj.FileExtension = self.__GetFileExtension() + elif self.__GetNextToken(): + if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\ + "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"): + + if self.__Token.startswith('PCD'): + self.__UndoToken() + self.__GetNextWord() + + if self.__Token == 'PCD': + if not self.__IsToken( "("): + raise Warning("expected '('", self.FileName, self.CurrentLineNumber) + PcdPair = self.__GetNextPcdName() + if not self.__IsToken( ")"): + raise Warning("expected ')'", self.FileName, self.CurrentLineNumber) + self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')' + + EfiSectionObj.FileName = self.__Token + + else: + self.__UndoToken() + else: + raise Warning("expected section file name", self.FileName, self.CurrentLineNumber) + + Obj.SectionList.append(EfiSectionObj) + return True + + ## __RuleSectionCouldBeOptional() method + # + # Get whether a section could be optional + # + # @param self The object pointer + # @param SectionType The section type to check + # @retval True section could be optional + # @retval False section never optional + # + def __RuleSectionCouldBeOptional(self, SectionType): + if SectionType in ("DXE_DEPEX", "UI", "VERSION", "PEI_DEPEX", "RAW", "SMM_DEPEX"): + return True + else: + return False + + ## __RuleSectionCouldHaveBuildNum() method + # + # Get whether a section could have build number information + # + # @param self The object pointer + # @param SectionType The section type to check + # @retval True section could have build number information + # @retval False section never have build number information + # + def __RuleSectionCouldHaveBuildNum(self, SectionType): + if SectionType in ("VERSION"): + return True + else: + return False + + ## __RuleSectionCouldHaveString() method + # + # Get whether a section could have string + # + # @param self The object pointer + # @param SectionType The section type to check + # @retval True section could have string + # @retval False section never have string + # + def __RuleSectionCouldHaveString(self, SectionType): + if SectionType in ("UI", "VERSION"): + return True + else: + return False + + ## __CheckRuleSectionFileType() method + # + # Get whether a section matches a file type + # + # @param self The object pointer + # @param SectionType The section type to check + # @param FileType The file type to check + # + def __CheckRuleSectionFileType(self, SectionType, FileType): + if SectionType == "COMPAT16": + if FileType not in ("COMPAT16", "SEC_COMPAT16"): + raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == "PE32": + if FileType not in ("PE32", "SEC_PE32"): + raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == "PIC": + if FileType not in ("PIC", "PIC"): + raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == "TE": + if FileType not in ("TE", "SEC_TE"): + raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == "RAW": + if FileType not in ("BIN", "SEC_BIN", "RAW", "ASL", "ACPI"): + raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == "DXE_DEPEX": + if FileType not in ("DXE_DEPEX", "SEC_DXE_DEPEX"): + raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == "UI": + if FileType not in ("UI", "SEC_UI"): + raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == "VERSION": + if FileType not in ("VERSION", "SEC_VERSION"): + raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == "PEI_DEPEX": + if FileType not in ("PEI_DEPEX", "SEC_PEI_DEPEX"): + raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == "GUID": + if FileType not in ("PE32", "SEC_GUID"): + raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) + + ## __GetRuleEncapsulationSection() method + # + # Get encapsulation section for Rule + # + # @param self The object pointer + # @param Rule for whom section is got + # @retval True Successfully find section statement + # @retval False Not able to find section statement + # + def __GetRuleEncapsulationSection(self, Rule): + + if self.__IsKeyword( "COMPRESS"): + Type = "PI_STD" + if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"): + Type = self.__Token + + if not self.__IsToken("{"): + raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) + + CompressSectionObj = CompressSection.CompressSection() + + CompressSectionObj.CompType = Type + # Recursive sections... + while True: + IsEncapsulate = self.__GetRuleEncapsulationSection(CompressSectionObj) + IsLeaf = self.__GetEfiSection(CompressSectionObj) + if not IsEncapsulate and not IsLeaf: + break + + if not self.__IsToken( "}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + Rule.SectionList.append(CompressSectionObj) + + return True + + elif self.__IsKeyword( "GUIDED"): + GuidValue = None + if self.__GetNextGuid(): + GuidValue = self.__Token + + if self.__IsKeyword( "$(NAMED_GUID)"): + GuidValue = self.__Token + + AttribDict = self.__GetGuidAttrib() + + if not self.__IsToken("{"): + raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) + GuidSectionObj = GuidSection.GuidSection() + GuidSectionObj.NameGuid = GuidValue + GuidSectionObj.SectionType = "GUIDED" + GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"] + GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"] + + # Efi sections... + while True: + IsEncapsulate = self.__GetRuleEncapsulationSection(GuidSectionObj) + IsLeaf = self.__GetEfiSection(GuidSectionObj) + if not IsEncapsulate and not IsLeaf: + break + + if not self.__IsToken( "}"): + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + Rule.SectionList.append(GuidSectionObj) + + return True + + return False + + ## __GetVtf() method + # + # Get VTF section contents and store its data into VTF list of self.Profile + # + # @param self The object pointer + # @retval True Successfully find a VTF + # @retval False Not able to find a VTF + # + def __GetVtf(self): + + if not self.__GetNextToken(): + return False + + S = self.__Token.upper() + if S.startswith("[") and not S.startswith("[VTF."): + if not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."): + raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber) + self.__UndoToken() + return False + + self.__UndoToken() + if not self.__IsToken("[VTF.", True): + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ + # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) + raise Warning("expected [VTF.]", self.FileName, self.CurrentLineNumber) + + if not self.__SkipToToken("."): + raise Warning("expected '.'", self.FileName, self.CurrentLineNumber) + + Arch = self.__SkippedChars.rstrip(".").upper() + if Arch not in ("IA32", "X64", "IPF", "ARM"): + raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber) + + if not self.__GetNextWord(): + raise Warning("expected VTF name", self.FileName, self.CurrentLineNumber) + Name = self.__Token.upper() + + VtfObj = Vtf.Vtf() + VtfObj.UiName = Name + VtfObj.KeyArch = Arch + + if self.__IsToken(","): + if not self.__GetNextWord(): + raise Warning("expected Arch list", self.FileName, self.CurrentLineNumber) + if self.__Token.upper() not in ("IA32", "X64", "IPF", "ARM"): + raise Warning("Unknown Arch '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + VtfObj.ArchList = self.__Token.upper() + + if not self.__IsToken( "]"): + raise Warning("expected ']'", self.FileName, self.CurrentLineNumber) + + if self.__IsKeyword("IA32_RST_BIN"): + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Reset file", self.FileName, self.CurrentLineNumber) + + VtfObj.ResetBin = self.__Token + + while self.__GetComponentStatement(VtfObj): + pass + + self.Profile.VtfList.append(VtfObj) + return True + + ## __GetComponentStatement() method + # + # Get components in VTF + # + # @param self The object pointer + # @param VtfObj for whom component is got + # @retval True Successfully find a component + # @retval False Not able to find a component + # + def __GetComponentStatement(self, VtfObj): + + if not self.__IsKeyword("COMP_NAME"): + return False + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextWord(): + raise Warning("expected Component Name", self.FileName, self.CurrentLineNumber) + + CompStatementObj = ComponentStatement.ComponentStatement() + CompStatementObj.CompName = self.__Token + + if not self.__IsKeyword("COMP_LOC"): + raise Warning("expected COMP_LOC", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + CompStatementObj.CompLoc = "" + if self.__GetNextWord(): + CompStatementObj.CompLoc = self.__Token + if self.__IsToken('|'): + if not self.__GetNextWord(): + raise Warning("Expected Region Name", self.FileName, self.CurrentLineNumber) + + if self.__Token not in ("F", "N", "S"): #, "H", "L", "PH", "PL"): not support + raise Warning("Unknown location type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + + CompStatementObj.FilePos = self.__Token + else: + self.CurrentLineNumber += 1 + self.CurrentOffsetWithinLine = 0 + + if not self.__IsKeyword("COMP_TYPE"): + raise Warning("expected COMP_TYPE", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Component type", self.FileName, self.CurrentLineNumber) + if self.__Token not in ("FIT", "PAL_B", "PAL_A", "OEM"): + if not self.__Token.startswith("0x") or len(self.__Token) < 3 or len(self.__Token) > 4 or \ + not self.__HexDigit(self.__Token[2]) or not self.__HexDigit(self.__Token[-1]): + raise Warning("Unknown location type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + CompStatementObj.CompType = self.__Token + + if not self.__IsKeyword("COMP_VER"): + raise Warning("expected COMP_VER", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Component version", self.FileName, self.CurrentLineNumber) + + Pattern = re.compile('-$|[0-9]{0,1}[0-9]{1}\.[0-9]{0,1}[0-9]{1}') + if Pattern.match(self.__Token) == None: + raise Warning("Unknown version format '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + CompStatementObj.CompVer = self.__Token + + if not self.__IsKeyword("COMP_CS"): + raise Warning("expected COMP_CS", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Component CS", self.FileName, self.CurrentLineNumber) + if self.__Token not in ("1", "0"): + raise Warning("Unknown Component CS '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + CompStatementObj.CompCs = self.__Token + + + if not self.__IsKeyword("COMP_BIN"): + raise Warning("expected COMP_BIN", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Component file", self.FileName, self.CurrentLineNumber) + + CompStatementObj.CompBin = self.__Token + + if not self.__IsKeyword("COMP_SYM"): + raise Warning("expected COMP_SYM", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if not self.__GetNextToken(): + raise Warning("expected Component symbol file", self.FileName, self.CurrentLineNumber) + + CompStatementObj.CompSym = self.__Token + + if not self.__IsKeyword("COMP_SIZE"): + raise Warning("expected COMP_SIZE", self.FileName, self.CurrentLineNumber) + + if not self.__IsToken("="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + + if self.__IsToken("-"): + CompStatementObj.CompSize = self.__Token + elif self.__GetNextDecimalNumber(): + CompStatementObj.CompSize = self.__Token + elif self.__GetNextHexNumber(): + CompStatementObj.CompSize = self.__Token + else: + raise Warning("Unknown size '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + + VtfObj.ComponentStatementList.append(CompStatementObj) + return True + + ## __GetOptionRom() method + # + # Get OptionROM section contents and store its data into OptionROM list of self.Profile + # + # @param self The object pointer + # @retval True Successfully find a OptionROM + # @retval False Not able to find a OptionROM + # + def __GetOptionRom(self): + + if not self.__GetNextToken(): + return False + + S = self.__Token.upper() + if S.startswith("[") and not S.startswith("[OPTIONROM."): + raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber) + + self.__UndoToken() + if not self.__IsToken("[OptionRom.", True): + raise Warning("Unknown Keyword '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) + + OptRomName = self.__GetUiName() + + if not self.__IsToken( "]"): + raise Warning("expected ']'", self.FileName, self.CurrentLineNumber) + + OptRomObj = OptionRom.OPTIONROM() + OptRomObj.DriverName = OptRomName + self.Profile.OptRomDict[OptRomName] = OptRomObj + + while True: + isInf = self.__GetOptRomInfStatement(OptRomObj) + isFile = self.__GetOptRomFileStatement(OptRomObj) + if not isInf and not isFile: + break + + return True + + ## __GetOptRomInfStatement() method + # + # Get INF statements + # + # @param self The object pointer + # @param Obj for whom inf statement is got + # @retval True Successfully find inf statement + # @retval False Not able to find inf statement + # + def __GetOptRomInfStatement(self, Obj): + + if not self.__IsKeyword( "INF"): + return False + + ffsInf = OptRomInfStatement.OptRomInfStatement() + self.__GetInfOptions( ffsInf) + + if not self.__GetNextToken(): + raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber) + ffsInf.InfFileName = self.__Token + + if not ffsInf.InfFileName in self.Profile.InfList: + self.Profile.InfList.append(ffsInf.InfFileName) + + + self.__GetOptRomOverrides (ffsInf) + + Obj.FfsList.append(ffsInf) + return True + + ## __GetOptRomOverrides() method + # + # Get overrides for OptROM INF & FILE + # + # @param self The object pointer + # @param FfsInfObj for whom overrides is got + # + def __GetOptRomOverrides(self, Obj): + if self.__IsToken('{'): + Overrides = OptionRom.OverrideAttribs() + if self.__IsKeyword( "PCI_VENDOR_ID"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextHexNumber(): + raise Warning("expected Hex vendor id", self.FileName, self.CurrentLineNumber) + Overrides.PciVendorId = self.__Token + + if self.__IsKeyword( "PCI_CLASS_CODE"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextHexNumber(): + raise Warning("expected Hex class code", self.FileName, self.CurrentLineNumber) + Overrides.PciClassCode = self.__Token + + if self.__IsKeyword( "PCI_DEVICE_ID"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextHexNumber(): + raise Warning("expected Hex device id", self.FileName, self.CurrentLineNumber) + + Overrides.PciDeviceId = self.__Token + + if self.__IsKeyword( "PCI_REVISION"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextHexNumber(): + raise Warning("expected Hex revision", self.FileName, self.CurrentLineNumber) + Overrides.PciRevision = self.__Token + + if self.__IsKeyword( "COMPRESS"): + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + if not self.__GetNextToken(): + raise Warning("expected TRUE/FALSE for compress", self.FileName, self.CurrentLineNumber) + + if self.__Token.upper() == 'TRUE': + Overrides.NeedCompress = True + + if not self.__IsToken( "}"): + + if self.__Token not in ("PCI_CLASS_CODE", "PCI_VENDOR_ID", "PCI_DEVICE_ID", "PCI_REVISION", "COMPRESS"): + raise Warning("unknown attribute %s" % self.__Token, self.FileName, self.CurrentLineNumber) + + raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + + Obj.OverrideAttribs = Overrides + + ## __GetOptRomFileStatement() method + # + # Get FILE statements + # + # @param self The object pointer + # @param Obj for whom FILE statement is got + # @retval True Successfully find FILE statement + # @retval False Not able to find FILE statement + # + def __GetOptRomFileStatement(self, Obj): + + if not self.__IsKeyword( "FILE"): + return False + + FfsFileObj = OptRomFileStatement.OptRomFileStatement() + + if not self.__IsKeyword("EFI") and not self.__IsKeyword("BIN"): + raise Warning("expected Binary type (EFI/BIN)", self.FileName, self.CurrentLineNumber) + FfsFileObj.FileType = self.__Token + + if not self.__GetNextToken(): + raise Warning("expected File path", self.FileName, self.CurrentLineNumber) + FfsFileObj.FileName = self.__Token + + if FfsFileObj.FileType == 'EFI': + self.__GetOptRomOverrides(FfsFileObj) + + Obj.FfsList.append(FfsFileObj) + + return True + + + ## __GetFvInFd() method + # + # Get FV list contained in FD + # + # @param self The object pointer + # @param FdName FD name + # @retval FvList list of FV in FD + # + def __GetFvInFd (self, FdName): + + FvList = [] + if FdName.upper() in self.Profile.FdDict.keys(): + FdObj = self.Profile.FdDict[FdName.upper()] + for elementRegion in FdObj.RegionList: + if elementRegion.RegionType == 'FV': + for elementRegionData in elementRegion.RegionDataList: + if elementRegionData != None and elementRegionData.upper() not in FvList: + FvList.append(elementRegionData.upper()) + return FvList + + ## __GetReferencedFdFvTuple() method + # + # Get FD and FV list referenced by a FFS file + # + # @param self The object pointer + # @param FfsFile contains sections to be searched + # @param RefFdList referenced FD by section + # @param RefFvList referenced FV by section + # + def __GetReferencedFdFvTuple(self, FvObj, RefFdList = [], RefFvList = []): + + for FfsObj in FvObj.FfsList: + if isinstance(FfsObj, FfsFileStatement.FileStatement): + if FfsObj.FvName != None and FfsObj.FvName.upper() not in RefFvList: + RefFvList.append(FfsObj.FvName.upper()) + elif FfsObj.FdName != None and FfsObj.FdName.upper() not in RefFdList: + RefFdList.append(FfsObj.FdName.upper()) + else: + self.__GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList) + + ## __GetReferencedFdFvTupleFromSection() method + # + # Get FD and FV list referenced by a FFS section + # + # @param self The object pointer + # @param FfsFile contains sections to be searched + # @param FdList referenced FD by section + # @param FvList referenced FV by section + # + def __GetReferencedFdFvTupleFromSection(self, FfsFile, FdList = [], FvList = []): + + SectionStack = [] + SectionStack.extend(FfsFile.SectionList) + while SectionStack != []: + SectionObj = SectionStack.pop() + if isinstance(SectionObj, FvImageSection.FvImageSection): + if SectionObj.FvName != None and SectionObj.FvName.upper() not in FvList: + FvList.append(SectionObj.FvName.upper()) + if SectionObj.Fv != None and SectionObj.Fv.UiFvName != None and SectionObj.Fv.UiFvName.upper() not in FvList: + FvList.append(SectionObj.Fv.UiFvName.upper()) + self.__GetReferencedFdFvTuple(SectionObj.Fv, FdList, FvList) + + if isinstance(SectionObj, CompressSection.CompressSection) or isinstance(SectionObj, GuidSection.GuidSection): + SectionStack.extend(SectionObj.SectionList) + + ## CycleReferenceCheck() method + # + # Check whether cycle reference exists in FDF + # + # @param self The object pointer + # @retval True cycle reference exists + # @retval False Not exists cycle reference + # + def CycleReferenceCheck(self): + + CycleRefExists = False + + try: + for FvName in self.Profile.FvDict.keys(): + LogStr = "Cycle Reference Checking for FV: %s\n" % FvName + RefFvStack = [] + RefFvStack.append(FvName) + FdAnalyzedList = [] + + while RefFvStack != []: + FvNameFromStack = RefFvStack.pop() + if FvNameFromStack.upper() in self.Profile.FvDict.keys(): + FvObj = self.Profile.FvDict[FvNameFromStack.upper()] + else: + continue + + RefFdList = [] + RefFvList = [] + self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList) + + for RefFdName in RefFdList: + if RefFdName in FdAnalyzedList: + continue + + LogStr += "FD %s is referenced by FV %s\n" % (RefFdName, FvNameFromStack) + FvInFdList = self.__GetFvInFd(RefFdName) + if FvInFdList != []: + LogStr += "FD %s contains FV: " % RefFdName + for FvObj in FvInFdList: + LogStr += FvObj + LogStr += ' \n' + if FvObj not in RefFvStack: + RefFvStack.append(FvObj) + + if FvName in RefFvStack: + CycleRefExists = True + raise Warning(LogStr) + FdAnalyzedList.append(RefFdName) + + for RefFvName in RefFvList: + LogStr += "FV %s is referenced by FV %s\n" % (RefFvName, FvNameFromStack) + if RefFvName not in RefFvStack: + RefFvStack.append(RefFvName) + + if FvName in RefFvStack: + CycleRefExists = True + raise Warning(LogStr) + + except Warning: + print LogStr + + finally: + return CycleRefExists + +if __name__ == "__main__": + parser = FdfParser("..\LakeportX64Pkg.fdf") + try: + parser.ParseFile() + parser.CycleReferenceCheck() + except Warning, X: + print str(X) + else: + print "Success!" + diff --git a/BaseTools/Source/Python/GenFds/Ffs.py b/BaseTools/Source/Python/GenFds/Ffs.py new file mode 100644 index 0000000000..aaa791763b --- /dev/null +++ b/BaseTools/Source/Python/GenFds/Ffs.py @@ -0,0 +1,81 @@ +## @file +# process FFS generation +# +# Copyright (c) 2007, 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 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 +# +from CommonDataClass.FdfClass import FDClassObject + +## generate FFS +# +# +class Ffs(FDClassObject): + + # mapping between MODULE type in FDF (from INF) and file type for GenFfs + ModuleTypeToFileType = { + 'SEC' : 'EFI_FV_FILETYPE_SECURITY_CORE', + 'PEI_CORE' : 'EFI_FV_FILETYPE_PEI_CORE', + 'PEIM' : 'EFI_FV_FILETYPE_PEIM', + 'DXE_CORE' : 'EFI_FV_FILETYPE_DXE_CORE', + 'DXE_DRIVER' : 'EFI_FV_FILETYPE_DRIVER', + 'DXE_SAL_DRIVER' : 'EFI_FV_FILETYPE_DRIVER', + 'DXE_SMM_DRIVER' : 'EFI_FV_FILETYPE_DRIVER', + 'DXE_RUNTIME_DRIVER': 'EFI_FV_FILETYPE_DRIVER', + 'UEFI_DRIVER' : 'EFI_FV_FILETYPE_DRIVER', + 'UEFI_APPLICATION' : 'EFI_FV_FILETYPE_APPLICATION', + 'SMM_DRIVER' : 'EFI_FV_FILETYPE_SMM', + 'SMM_CORE' : 'EFI_FV_FILETYPE_SMM_CORE' + } + + # mapping between FILE type in FDF and file type for GenFfs + FdfFvFileTypeToFileType = { + 'SEC' : 'EFI_FV_FILETYPE_SECURITY_CORE', + 'PEI_CORE' : 'EFI_FV_FILETYPE_PEI_CORE', + 'PEIM' : 'EFI_FV_FILETYPE_PEIM', + 'DXE_CORE' : 'EFI_FV_FILETYPE_DXE_CORE', + 'FREEFORM' : 'EFI_FV_FILETYPE_FREEFORM', + 'DRIVER' : 'EFI_FV_FILETYPE_DRIVER', + 'APPLICATION' : 'EFI_FV_FILETYPE_APPLICATION', + 'FV_IMAGE' : 'EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE', + 'RAW' : 'EFI_FV_FILETYPE_RAW', + 'PEI_DXE_COMBO' : 'EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER', + 'SMM_DXE_COMBO' : 'EFI_FV_FILETYPE_COMBINED_SMM_DXE', + 'SMM' : 'EFI_FV_FILETYPE_SMM', + 'SMM_CORE' : 'EFI_FV_FILETYPE_SMM_CORE' + } + + # mapping between section type in FDF and file suffix + SectionSuffix = { + 'PE32' : '.pe32', + 'PIC' : '.pic', + 'TE' : '.te', + 'DXE_DEPEX' : '.dpx', + 'VERSION' : '.ver', + 'UI' : '.ui', + 'COMPAT16' : '.com16', + 'RAW' : '.raw', + 'FREEFORM_SUBTYPE_GUID': '.guid', + 'FV_IMAGE' : 'fv.sec', + 'COMPRESS' : '.com', + 'GUIDED' : '.guided', + 'PEI_DEPEX' : '.dpx', + 'SMM_DEPEX' : '.smm' + } + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + FfsClassObject.__init__(self) diff --git a/BaseTools/Source/Python/GenFds/FfsFileStatement.py b/BaseTools/Source/Python/GenFds/FfsFileStatement.py new file mode 100644 index 0000000000..ed778f3d44 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/FfsFileStatement.py @@ -0,0 +1,118 @@ +## @file +# process FFS generation from FILE statement +# +# Copyright (c) 2007, 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 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 Ffs +import Rule +from GenFdsGlobalVariable import GenFdsGlobalVariable +import os +import StringIO +import subprocess +from CommonDataClass.FdfClass import FileStatementClassObject +from Common import EdkLogger +from Common.BuildToolError import * +from Common.Misc import GuidStructureByteArrayToGuidString + +## generate FFS from FILE +# +# +class FileStatement (FileStatementClassObject) : + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + FileStatementClassObject.__init__(self) + + ## GenFfs() method + # + # Generate FFS + # + # @param self The object pointer + # @param Dict dictionary contains macro and value pair + # @retval string Generated FFS file name + # + def GenFfs(self, Dict = {}): + + if self.NameGuid != None and self.NameGuid.startswith('PCD('): + PcdValue = GenFdsGlobalVariable.GetPcdValue(self.NameGuid) + if len(PcdValue) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \ + % (self.NameGuid)) + if PcdValue.startswith('{'): + PcdValue = GuidStructureByteArrayToGuidString(PcdValue) + RegistryGuidStr = PcdValue + if len(RegistryGuidStr) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \ + % (self.NameGuid)) + self.NameGuid = RegistryGuidStr + + OutputDir = os.path.join(GenFdsGlobalVariable.FfsDir, self.NameGuid) + if not os.path.exists(OutputDir): + os.makedirs(OutputDir) + + Dict.update(self.DefineVarDict) + SectionAlignments = None + if self.FvName != None : + Buffer = StringIO.StringIO('') + if self.FvName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys(): + EdkLogger.error("GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (self.FvName)) + Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName.upper()) + FileName = Fv.AddToBuffer(Buffer) + SectionFiles = [FileName] + + elif self.FdName != None: + if self.FdName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys(): + EdkLogger.error("GenFds", GENFDS_ERROR, "FD (%s) is NOT described in FDF file!" % (self.FdName)) + Fd = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(self.FdName.upper()) + FvBin = {} + FileName = Fd.GenFd(FvBin) + SectionFiles = [FileName] + + elif self.FileName != None: + self.FileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName) + SectionFiles = [GenFdsGlobalVariable.MacroExtend(self.FileName, Dict)] + + else: + SectionFiles = [] + Index = 0 + SectionAlignments = [] + for section in self.SectionList : + Index = Index + 1 + SecIndex = '%d' %Index + sectList, align = section.GenSection(OutputDir, self.NameGuid, SecIndex, self.KeyStringList, None, Dict) + if sectList != []: + for sect in sectList: + SectionFiles.append(sect) + SectionAlignments.append(align) + + # + # Prepare the parameter + # + FfsFileOutput = os.path.join(OutputDir, self.NameGuid + '.ffs') + GenFdsGlobalVariable.GenerateFfs(FfsFileOutput, SectionFiles, + Ffs.Ffs.FdfFvFileTypeToFileType.get(self.FvFileType), + self.NameGuid, + Fixed=self.Fixed, + CheckSum=self.CheckSum, + Align=self.Alignment, + SectionAlign=SectionAlignments + ) + + return FfsFileOutput + + + diff --git a/BaseTools/Source/Python/GenFds/FfsInfStatement.py b/BaseTools/Source/Python/GenFds/FfsInfStatement.py new file mode 100644 index 0000000000..0dcd96da2e --- /dev/null +++ b/BaseTools/Source/Python/GenFds/FfsInfStatement.py @@ -0,0 +1,582 @@ +## @file +# process FFS generation from INF statement +# +# Copyright (c) 2007, 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 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 Rule +import os +import shutil +from GenFdsGlobalVariable import GenFdsGlobalVariable +import Ffs +import subprocess +import sys +import Section +import RuleSimpleFile +import RuleComplexFile +from CommonDataClass.FdfClass import FfsInfStatementClassObject +from Common.String import * +from Common.Misc import PathClass +from Common.Misc import GuidStructureByteArrayToGuidString +from Common import EdkLogger +from Common.BuildToolError import * + +## generate FFS from INF +# +# +class FfsInfStatement(FfsInfStatementClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + FfsInfStatementClassObject.__init__(self) + self.TargetOverrideList = [] + self.ShadowFromInfFile = None + self.KeepRelocFromRule = None + self.InDsc = True + self.OptRomDefs = {} + + ## __InfParse() method + # + # Parse inf file to get module information + # + # @param self The object pointer + # @param Dict dictionary contains macro and value pair + # + def __InfParse__(self, Dict = {}): + + GenFdsGlobalVariable.VerboseLogger( " Begine parsing INf file : %s" %self.InfFileName) + + self.InfFileName = self.InfFileName.replace('$(WORKSPACE)', '') + if self.InfFileName[0] == '\\' or self.InfFileName[0] == '/' : + self.InfFileName = self.InfFileName[1:] + + if self.InfFileName.find('$') == -1: + InfPath = NormPath(self.InfFileName) + if not os.path.exists(InfPath): + InfPath = GenFdsGlobalVariable.ReplaceWorkspaceMacro(InfPath) + if not os.path.exists(InfPath): + EdkLogger.error("GenFds", GENFDS_ERROR, "Non-existant Module %s !" % (self.InfFileName)) + + self.CurrentArch = self.GetCurrentArch() + # + # Get the InfClass object + # + + PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir) + ErrorCode, ErrorInfo = PathClassObj.Validate() + if ErrorCode != 0: + EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) + + if self.CurrentArch != None: + + Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch] + # + # Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath + # + self.BaseName = Inf.BaseName + self.ModuleGuid = Inf.Guid + self.ModuleType = Inf.ModuleType + if Inf.AutoGenVersion < 0x00010005: + self.ModuleType = Inf.ComponentType + self.VersionString = Inf.Version + self.BinFileList = Inf.Binaries + self.SourceFileList = Inf.Sources + if self.KeepReloc == None and Inf.Shadow: + self.ShadowFromInfFile = Inf.Shadow + + else: + Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, 'COMMON'] + self.BaseName = Inf.BaseName + self.ModuleGuid = Inf.Guid + self.ModuleType = Inf.ModuleType + self.VersionString = Inf.Version + self.BinFileList = Inf.Binaries + self.SourceFileList = Inf.Sources + if self.BinFileList == []: + EdkLogger.error("GenFds", GENFDS_ERROR, + "INF %s specified in FDF could not be found in build ARCH %s!" \ + % (self.InfFileName, GenFdsGlobalVariable.ArchList)) + + if len(self.SourceFileList) != 0 and not self.InDsc: + EdkLogger.warn("GenFds", GENFDS_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % (self.InfFileName)) + + if Inf._Defs != None and len(Inf._Defs) > 0: + self.OptRomDefs.update(Inf._Defs) + + GenFdsGlobalVariable.VerboseLogger( "BaseName : %s" %self.BaseName) + GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" %self.ModuleGuid) + GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" %self.ModuleType) + GenFdsGlobalVariable.VerboseLogger("VersionString : %s" %self.VersionString) + GenFdsGlobalVariable.VerboseLogger("InfFileName :%s" %self.InfFileName) + + # + # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\ + # + + self.OutputPath = os.path.join(GenFdsGlobalVariable.FfsDir, \ + self.ModuleGuid + self.BaseName) + if not os.path.exists(self.OutputPath) : + os.makedirs(self.OutputPath) + + self.EfiOutputPath = self.__GetEFIOutPutPath__() + GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath) + + ## GenFfs() method + # + # Generate FFS + # + # @param self The object pointer + # @param Dict dictionary contains macro and value pair + # @retval string Generated FFS file name + # + def GenFfs(self, Dict = {}): + # + # Parse Inf file get Module related information + # + + self.__InfParse__(Dict) + # + # Get the rule of how to generate Ffs file + # + Rule = self.__GetRule__() + GenFdsGlobalVariable.VerboseLogger( "Packing binaries from inf file : %s" %self.InfFileName) + #FileType = Ffs.Ffs.ModuleTypeToFileType[Rule.ModuleType] + # + # For the rule only has simpleFile + # + if isinstance (Rule, RuleSimpleFile.RuleSimpleFile) : + SectionOutputList = self.__GenSimpleFileSection__(Rule) + FfsOutput = self.__GenSimpleFileFfs__(Rule, SectionOutputList) + return FfsOutput + # + # For Rule has ComplexFile + # + elif isinstance(Rule, RuleComplexFile.RuleComplexFile): + InputSectList, InputSectAlignments = self.__GenComplexFileSection__(Rule) + FfsOutput = self.__GenComplexFileFfs__(Rule, InputSectList, InputSectAlignments) + + return FfsOutput + + ## __ExtendMacro__() method + # + # Replace macro with its value + # + # @param self The object pointer + # @param String The string to be replaced + # @retval string Macro replaced string + # + def __ExtendMacro__ (self, String): + MacroDict = { + '$(INF_OUTPUT)' : self.EfiOutputPath, + '$(MODULE_NAME)' : self.BaseName, + '$(BUILD_NUMBER)': self.BuildNum, + '$(INF_VERSION)' : self.VersionString, + '$(NAMED_GUID)' : self.ModuleGuid + } + String = GenFdsGlobalVariable.MacroExtend(String, MacroDict) + return String + + ## __GetRule__() method + # + # Get correct rule for generating FFS for this INF + # + # @param self The object pointer + # @retval Rule Rule object + # + def __GetRule__ (self) : + CurrentArchList = [] + if self.CurrentArch == None: + CurrentArchList = ['common'] + else: + CurrentArchList.append(self.CurrentArch) + + for CurrentArch in CurrentArchList: + RuleName = 'RULE' + \ + '.' + \ + CurrentArch.upper() + \ + '.' + \ + self.ModuleType.upper() + if self.Rule != None: + RuleName = RuleName + \ + '.' + \ + self.Rule.upper() + + Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName) + if Rule != None: + GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName) + return Rule + + RuleName = 'RULE' + \ + '.' + \ + 'COMMON' + \ + '.' + \ + self.ModuleType.upper() + + if self.Rule != None: + RuleName = RuleName + \ + '.' + \ + self.Rule.upper() + + GenFdsGlobalVariable.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName, self.InfFileName)) + + Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName) + if Rule != None: + GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName) + return Rule + + if Rule == None : + EdkLogger.error("GenFds", GENFDS_ERROR, 'Don\'t Find common rule %s for INF %s' \ + % (RuleName, self.InfFileName)) + + ## __GetPlatformArchList__() method + # + # Get Arch list this INF built under + # + # @param self The object pointer + # @retval list Arch list + # + def __GetPlatformArchList__(self): + + InfFileKey = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName)) + DscArchList = [] + PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IA32'] + if PlatformDataBase != None: + if InfFileKey in PlatformDataBase.Modules: + DscArchList.append ('IA32') + + PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'X64'] + if PlatformDataBase != None: + if InfFileKey in PlatformDataBase.Modules: + DscArchList.append ('X64') + + PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IPF'] + if PlatformDataBase != None: + if InfFileKey in (PlatformDataBase.Modules): + DscArchList.append ('IPF') + + PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'ARM'] + if PlatformDataBase != None: + if InfFileKey in (PlatformDataBase.Modules): + DscArchList.append ('ARM') + + PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'EBC'] + if PlatformDataBase != None: + if InfFileKey in (PlatformDataBase.Modules): + DscArchList.append ('EBC') + + return DscArchList + + ## GetCurrentArch() method + # + # Get Arch list of the module from this INF is to be placed into flash + # + # @param self The object pointer + # @retval list Arch list + # + def GetCurrentArch(self) : + + TargetArchList = GenFdsGlobalVariable.ArchList + + PlatformArchList = self.__GetPlatformArchList__() + + CurArchList = TargetArchList + if PlatformArchList != []: + CurArchList = list(set (TargetArchList) & set (PlatformArchList)) + GenFdsGlobalVariable.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList)) + + ArchList = [] + if self.KeyStringList != []: + for Key in self.KeyStringList: + Key = GenFdsGlobalVariable.MacroExtend(Key) + Target, Tag, Arch = Key.split('_') + if Arch in CurArchList: + ArchList.append(Arch) + if Target not in self.TargetOverrideList: + self.TargetOverrideList.append(Target) + else: + ArchList = CurArchList + + UseArchList = TargetArchList + if self.UseArch != None: + UseArchList = [] + UseArchList.append(self.UseArch) + ArchList = list(set (UseArchList) & set (ArchList)) + + self.InfFileName = NormPath(self.InfFileName) + if len(PlatformArchList) == 0: + self.InDsc = False + PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir) + ErrorCode, ErrorInfo = PathClassObj.Validate() + if ErrorCode != 0: + EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) + if len(ArchList) == 1: + Arch = ArchList[0] + return Arch + elif len(ArchList) > 1: + if len(PlatformArchList) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, "GenFds command line option has multiple ARCHs %s. Not able to determine which ARCH is valid for Module %s !" % (str(ArchList), self.InfFileName)) + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "Module built under multiple ARCHs %s. Not able to determine which output to put into flash for Module %s !" % (str(ArchList), self.InfFileName)) + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s appears under ARCH %s in platform %s, but current deduced ARCH is %s, so NO build output could be put into flash." \ + % (self.InfFileName, str(PlatformArchList), GenFdsGlobalVariable.ActivePlatform, str(set (UseArchList) & set (TargetArchList)))) + + ## __GetEFIOutPutPath__() method + # + # Get the output path for generated files + # + # @param self The object pointer + # @retval string Path that output files from this INF go to + # + def __GetEFIOutPutPath__(self): + Arch = '' + OutputPath = '' + (ModulePath, FileName) = os.path.split(self.InfFileName) + Index = FileName.find('.') + FileName = FileName[0:Index] + Arch = "NoneArch" + if self.CurrentArch != None: + Arch = self.CurrentArch + + OutputPath = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], + Arch , + ModulePath, + FileName, + 'OUTPUT' + ) + OutputPath = os.path.realpath(OutputPath) + return OutputPath + + ## __GenSimpleFileSection__() method + # + # Generate section by specified file name or a list of files with file extension + # + # @param self The object pointer + # @param Rule The rule object used to generate section + # @retval string File name of the generated section file + # + def __GenSimpleFileSection__(self, Rule): + # + # Prepare the parameter of GenSection + # + FileList = [] + OutputFileList = [] + if Rule.FileName != None: + GenSecInputFile = self.__ExtendMacro__(Rule.FileName) + else: + FileList, IsSect = Section.Section.GetFileList(self, '', Rule.FileExtension) + + Index = 1 + SectionType = Rule.SectionType + NoStrip = True + if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'): + if self.KeepReloc != None: + NoStrip = self.KeepReloc + elif Rule.KeepReloc != None: + NoStrip = Rule.KeepReloc + elif self.ShadowFromInfFile != None: + NoStrip = self.ShadowFromInfFile + + if FileList != [] : + for File in FileList: + + SecNum = '%d' %Index + GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \ + Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum + Index = Index + 1 + OutputFile = os.path.join(self.OutputPath, GenSecOutputFile) + + if not NoStrip: + FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc') + if not os.path.exists(FileBeforeStrip) or \ + (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)): + shutil.copyfile(File, FileBeforeStrip) + StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped') + GenFdsGlobalVariable.GenerateFirmwareImage( + StrippedFile, + [GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch)], + Strip=True + ) + File = StrippedFile + + if SectionType == 'TE': + TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw') + GenFdsGlobalVariable.GenerateFirmwareImage( + TeFile, + [GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch)], + Type='te' + ) + File = TeFile + + GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType]) + OutputFileList.append(OutputFile) + else: + SecNum = '%d' %Index + GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \ + Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum + OutputFile = os.path.join(self.OutputPath, GenSecOutputFile) + + if not NoStrip: + FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc') + if not os.path.exists(FileBeforeStrip) or \ + (os.path.getmtime(GenSecInputFile) > os.path.getmtime(FileBeforeStrip)): + shutil.copyfile(GenSecInputFile, FileBeforeStrip) + StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped') + GenFdsGlobalVariable.GenerateFirmwareImage( + StrippedFile, + [GenFdsGlobalVariable.MacroExtend(GenSecInputFile, Dict, self.CurrentArch)], + Strip=True + ) + GenSecInputFile = StrippedFile + + if SectionType == 'TE': + TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw') + GenFdsGlobalVariable.GenerateFirmwareImage( + TeFile, + [GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch)], + Type='te' + ) + GenSecInputFile = TeFile + + GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType]) + OutputFileList.append(OutputFile) + + return OutputFileList + + ## __GenSimpleFileFfs__() method + # + # Generate FFS + # + # @param self The object pointer + # @param Rule The rule object used to generate section + # @param InputFileList The output file list from GenSection + # @retval string Generated FFS file name + # + def __GenSimpleFileFfs__(self, Rule, InputFileList): + FfsOutput = self.OutputPath + \ + os.sep + \ + self.__ExtendMacro__(Rule.NameGuid) + \ + '.ffs' + + GenFdsGlobalVariable.VerboseLogger(self.__ExtendMacro__(Rule.NameGuid)) + InputSection = [] + SectionAlignments = [] + for InputFile in InputFileList: + InputSection.append(InputFile) + SectionAlignments.append(Rule.Alignment) + + if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('): + PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid) + if len(PcdValue) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \ + % (Rule.NameGuid)) + if PcdValue.startswith('{'): + PcdValue = GuidStructureByteArrayToGuidString(PcdValue) + RegistryGuidStr = PcdValue + if len(RegistryGuidStr) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \ + % (Rule.NameGuid)) + self.ModuleGuid = RegistryGuidStr + + GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputSection, + Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType], + self.ModuleGuid, Fixed=Rule.Fixed, + CheckSum=Rule.CheckSum, Align=Rule.Alignment, + SectionAlign=SectionAlignments + ) + return FfsOutput + + ## __GenComplexFileSection__() method + # + # Generate section by sections in Rule + # + # @param self The object pointer + # @param Rule The rule object used to generate section + # @retval string File name of the generated section file + # + def __GenComplexFileSection__(self, Rule): + if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'): + if Rule.KeepReloc != None: + self.KeepRelocFromRule = Rule.KeepReloc + SectFiles = [] + SectAlignments = [] + Index = 1 + for Sect in Rule.SectionList: + SecIndex = '%d' %Index + SectList = [] + if Rule.KeyStringList != []: + SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, Rule.KeyStringList, self) + else : + SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, self.KeyStringList, self) + for SecName in SectList : + SectFiles.append(SecName) + SectAlignments.append(Align) + Index = Index + 1 + return SectFiles, SectAlignments + + ## __GenComplexFileFfs__() method + # + # Generate FFS + # + # @param self The object pointer + # @param Rule The rule object used to generate section + # @param InputFileList The output file list from GenSection + # @retval string Generated FFS file name + # + def __GenComplexFileFfs__(self, Rule, InputFile, Alignments): + + if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('): + PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid) + if len(PcdValue) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \ + % (Rule.NameGuid)) + if PcdValue.startswith('{'): + PcdValue = GuidStructureByteArrayToGuidString(PcdValue) + RegistryGuidStr = PcdValue + if len(RegistryGuidStr) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \ + % (Rule.NameGuid)) + self.ModuleGuid = RegistryGuidStr + + FfsOutput = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs') + GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputFile, + Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType], + self.ModuleGuid, Fixed=Rule.Fixed, + CheckSum=Rule.CheckSum, Align=Rule.Alignment, + SectionAlign=Alignments + ) + return FfsOutput + + ## __GetGenFfsCmdParameter__() method + # + # Create parameter string for GenFfs + # + # @param self The object pointer + # @param Rule The rule object used to generate section + # @retval tuple (FileType, Fixed, CheckSum, Alignment) + # + def __GetGenFfsCmdParameter__(self, Rule): + result = tuple() + result += ('-t', Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType]) + if Rule.Fixed != False: + result += ('-x',) + if Rule.CheckSum != False: + result += ('-s',) + + if Rule.Alignment != None and Rule.Alignment != '': + result += ('-a', Rule.Alignment) + + return result diff --git a/BaseTools/Source/Python/GenFds/Fv.py b/BaseTools/Source/Python/GenFds/Fv.py new file mode 100644 index 0000000000..74248f71c3 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/Fv.py @@ -0,0 +1,215 @@ +## @file +# process FV generation +# +# Copyright (c) 2007, 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 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 shutil +import subprocess +import StringIO + +import Ffs +import AprioriSection +from GenFdsGlobalVariable import GenFdsGlobalVariable +from GenFds import GenFds +from CommonDataClass.FdfClass import FvClassObject +from Common.Misc import SaveFileOnChange + +T_CHAR_LF = '\n' + +## generate FV +# +# +class FV (FvClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + FvClassObject.__init__(self) + self.FvInfFile = None + self.FvAddressFile = None + self.BaseAddress = None + self.InfFileName = None + self.FvAddressFileName = None + + ## AddToBuffer() + # + # Generate Fv and add it to the Buffer + # + # @param self The object pointer + # @param Buffer The buffer generated FV data will be put + # @param BaseAddress base address of FV + # @param BlockSize block size of FV + # @param BlockNum How many blocks in FV + # @param ErasePolarity Flash erase polarity + # @param VtfDict VTF objects + # @param MacroDict macro value pair + # @retval string Generated FV file path + # + def AddToBuffer (self, Buffer, BaseAddress=None, BlockSize= None, BlockNum=None, ErasePloarity='1', VtfDict=None, MacroDict = {}) : + + if self.UiFvName.upper() in GenFds.FvBinDict.keys(): + return GenFds.FvBinDict[self.UiFvName.upper()] + + GenFdsGlobalVariable.InfLogger( "\nGenerating %s FV ..." %self.UiFvName) + + self.__InitializeInf__(BaseAddress, BlockSize, BlockNum, ErasePloarity, VtfDict) + # + # First Process the Apriori section + # + MacroDict.update(self.DefineVarDict) + + GenFdsGlobalVariable.VerboseLogger('First generate Apriori file !') + FfsFileList = [] + for AprSection in self.AprioriSectionList: + FileName = AprSection.GenFfs (self.UiFvName, MacroDict) + FfsFileList.append(FileName) + # Add Apriori file name to Inf file + self.FvInfFile.writelines("EFI_FILE_NAME = " + \ + FileName + \ + T_CHAR_LF) + + # Process Modules in FfsList + for FfsFile in self.FfsList : + FileName = FfsFile.GenFfs(MacroDict) + FfsFileList.append(FileName) + self.FvInfFile.writelines("EFI_FILE_NAME = " + \ + FileName + \ + T_CHAR_LF) + + SaveFileOnChange(self.InfFileName, self.FvInfFile.getvalue(), False) + self.FvInfFile.close() + # + # Call GenFv tool + # + FvOutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.UiFvName) + FvOutputFile = FvOutputFile + '.Fv' + # BUGBUG: FvOutputFile could be specified from FDF file (FV section, CreateFile statement) + if self.CreateFileName != None: + FvOutputFile = self.CreateFileName + + FvInfoFileName = os.path.join(GenFdsGlobalVariable.FfsDir, self.UiFvName + '.inf') + shutil.copy(GenFdsGlobalVariable.FvAddressFileName, FvInfoFileName) + GenFdsGlobalVariable.GenerateFirmwareVolume( + FvOutputFile, + [self.InfFileName], + AddressFile=FvInfoFileName, + FfsList=FfsFileList + ) + + # + # Write the Fv contents to Buffer + # + FvFileObj = open ( FvOutputFile,'r+b') + + GenFdsGlobalVariable.InfLogger( "\nGenerate %s FV Successfully" %self.UiFvName) + GenFdsGlobalVariable.SharpCounter = 0 + + Buffer.write(FvFileObj.read()) + FvFileObj.close() + GenFds.FvBinDict[self.UiFvName.upper()] = FvOutputFile + return FvOutputFile + + ## __InitializeInf__() + # + # Initilize the inf file to create FV + # + # @param self The object pointer + # @param BaseAddress base address of FV + # @param BlockSize block size of FV + # @param BlockNum How many blocks in FV + # @param ErasePolarity Flash erase polarity + # @param VtfDict VTF objects + # + def __InitializeInf__ (self, BaseAddress = None, BlockSize= None, BlockNum = None, ErasePloarity='1', VtfDict=None) : + # + # Create FV inf file + # + self.InfFileName = os.path.join(GenFdsGlobalVariable.FvDir, + self.UiFvName + '.inf') + self.FvInfFile = StringIO.StringIO() + + # + # Add [Options] + # + self.FvInfFile.writelines("[options]" + T_CHAR_LF) + if BaseAddress != None : + self.FvInfFile.writelines("EFI_BASE_ADDRESS = " + \ + BaseAddress + \ + T_CHAR_LF) + + if BlockSize != None: + self.FvInfFile.writelines("EFI_BLOCK_SIZE = " + \ + '0x%X' %BlockSize + \ + T_CHAR_LF) + if BlockNum != None: + self.FvInfFile.writelines("EFI_NUM_BLOCKS = " + \ + ' 0x%X' %BlockNum + \ + T_CHAR_LF) + else: + for BlockSize in self.BlockSizeList : + if BlockSize[0] != None: + self.FvInfFile.writelines("EFI_BLOCK_SIZE = " + \ + '0x%X' %BlockSize[0] + \ + T_CHAR_LF) + + if BlockSize[1] != None: + self.FvInfFile.writelines("EFI_NUM_BLOCKS = " + \ + ' 0x%X' %BlockSize[1] + \ + T_CHAR_LF) + + if self.BsBaseAddress != None: + self.FvInfFile.writelines('EFI_BOOT_DRIVER_BASE_ADDRESS = ' + \ + '0x%X' %self.BsBaseAddress) + if self.RtBaseAddress != None: + self.FvInfFile.writelines('EFI_RUNTIME_DRIVER_BASE_ADDRESS = ' + \ + '0x%X' %self.RtBaseAddress) + # + # Add attribute + # + self.FvInfFile.writelines("[attributes]" + T_CHAR_LF) + + self.FvInfFile.writelines("EFI_ERASE_POLARITY = " + \ + ' %s' %ErasePloarity + \ + T_CHAR_LF) + if not (self.FvAttributeDict == None): + for FvAttribute in self.FvAttributeDict.keys() : + self.FvInfFile.writelines("EFI_" + \ + FvAttribute + \ + ' = ' + \ + self.FvAttributeDict[FvAttribute] + \ + T_CHAR_LF ) + if self.FvAlignment != None: + self.FvInfFile.writelines("EFI_FVB2_ALIGNMENT_" + \ + self.FvAlignment.strip() + \ + " = TRUE" + \ + T_CHAR_LF) + + if self.FvNameGuid != None: + self.FvInfFile.writelines("EFI_FVNAME_GUID" + \ + " = %s" % self.FvNameGuid + \ + T_CHAR_LF) + # + # Add [Files] + # + + self.FvInfFile.writelines("[files]" + T_CHAR_LF) + if VtfDict != None and self.UiFvName in VtfDict.keys(): + self.FvInfFile.writelines("EFI_FILE_NAME = " + \ + VtfDict.get(self.UiFvName) + \ + T_CHAR_LF) + + diff --git a/BaseTools/Source/Python/GenFds/FvImageSection.py b/BaseTools/Source/Python/GenFds/FvImageSection.py new file mode 100644 index 0000000000..3a3e714228 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/FvImageSection.py @@ -0,0 +1,90 @@ +## @file +# process FV image section generation +# +# Copyright (c) 2007, 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 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 Section +import StringIO +from Ffs import Ffs +import subprocess +from GenFdsGlobalVariable import GenFdsGlobalVariable +import os +from CommonDataClass.FdfClass import FvImageSectionClassObject +from Common import EdkLogger +from Common.BuildToolError import * + +## generate FV image section +# +# +class FvImageSection(FvImageSectionClassObject): + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + FvImageSectionClassObject.__init__(self) + + ## GenSection() method + # + # Generate FV image section + # + # @param self The object pointer + # @param OutputPath Where to place output file + # @param ModuleName Which module this section belongs to + # @param SecNum Index of section + # @param KeyStringList Filter for inputs of section generation + # @param FfsInf FfsInfStatement object that contains this section data + # @param Dict dictionary contains macro and its value + # @retval tuple (Generated file name, section alignment) + # + def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}): + + OutputFileList = [] + if self.FvFileType != None: + FileList, IsSect = Section.Section.GetFileList(FfsInf, self.FvFileType, self.FvFileExtension) + if IsSect : + return FileList, self.Alignment + + Num = SecNum + + for FileName in FileList: + OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + Num + Ffs.SectionSuffix.get("FV_IMAGE")) + GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE') + OutputFileList.append(OutputFile) + return OutputFileList, self.Alignment + # + # Generate Fv + # + if self.FvName != None: + Buffer = StringIO.StringIO('') + Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName) + if Fv != None: + self.Fv = Fv + FvFileName = self.Fv.AddToBuffer(Buffer, MacroDict = Dict) + else: + if self.FvFileName != None: + FvFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FvFileName) + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "FvImageSection Failed! %s NOT found in FDF" % self.FvName) + + # + # Prepare the parameter of GenSection + # + OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + SecNum + Ffs.SectionSuffix.get("FV_IMAGE")) + GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE') + OutputFileList.append(OutputFile) + + return OutputFileList, self.Alignment diff --git a/BaseTools/Source/Python/GenFds/GenFds.py b/BaseTools/Source/Python/GenFds/GenFds.py new file mode 100644 index 0000000000..2bc416f828 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/GenFds.py @@ -0,0 +1,486 @@ +## @file +# generate flash image +# +# Copyright (c) 2007, 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 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 +# +from optparse import OptionParser +import sys +import os +import linecache +import FdfParser +from Common.BuildToolError import * +from GenFdsGlobalVariable import GenFdsGlobalVariable +from Workspace.WorkspaceDatabase import WorkspaceDatabase +from Workspace.BuildClassObject import PcdClassObject +from Workspace.BuildClassObject import ModuleBuildClassObject +import RuleComplexFile +from EfiSection import EfiSection +import StringIO +import Common.TargetTxtClassObject as TargetTxtClassObject +import Common.ToolDefClassObject as ToolDefClassObject +import Common.DataType +import Common.GlobalData as GlobalData +from Common import EdkLogger +from Common.String import * +from Common.Misc import DirCache,PathClass + +## Version and Copyright +versionNumber = "1.0" +__version__ = "%prog Version " + versionNumber +__copyright__ = "Copyright (c) 2007, Intel Corporation All rights reserved." + +## 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(): + global Options + Options = myOptionParser() + + global Workspace + Workspace = "" + ArchList = None + ReturnCode = 0 + + EdkLogger.Initialize() + try: + if Options.verbose != None: + EdkLogger.SetLevel(EdkLogger.VERBOSE) + GenFdsGlobalVariable.VerboseMode = True + + if Options.FixedAddress != None: + GenFdsGlobalVariable.FixedLoadAddress = True + + if Options.quiet != None: + EdkLogger.SetLevel(EdkLogger.QUIET) + if Options.debug != None: + EdkLogger.SetLevel(Options.debug + 1) + GenFdsGlobalVariable.DebugLevel = Options.debug + else: + EdkLogger.SetLevel(EdkLogger.INFO) + + if (Options.Workspace == None): + EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "WORKSPACE not defined", + ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.") + elif not os.path.exists(Options.Workspace): + EdkLogger.error("GenFds", BuildToolError.PARAMETER_INVALID, "WORKSPACE is invalid", + ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.") + else: + Workspace = os.path.normcase(Options.Workspace) + GenFdsGlobalVariable.WorkSpaceDir = Workspace + if 'EDK_SOURCE' in os.environ.keys(): + GenFdsGlobalVariable.EdkSourceDir = os.path.normcase(os.environ['EDK_SOURCE']) + if (Options.debug): + GenFdsGlobalVariable.VerboseLogger( "Using Workspace:" + Workspace) + os.chdir(GenFdsGlobalVariable.WorkSpaceDir) + + if (Options.filename): + FdfFilename = Options.filename + FdfFilename = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdfFilename) + else: + EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing FDF filename") + + if (Options.BuildTarget): + GenFdsGlobalVariable.TargetName = Options.BuildTarget + else: + EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing build target") + + if (Options.ToolChain): + GenFdsGlobalVariable.ToolChainTag = Options.ToolChain + else: + EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing tool chain tag") + + if FdfFilename[0:2] == '..': + FdfFilename = os.path.realpath(FdfFilename) + if FdfFilename[1] != ':': + FdfFilename = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, FdfFilename) + + if not os.path.exists(FdfFilename): + EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, ExtraData=FdfFilename) + GenFdsGlobalVariable.FdfFile = FdfFilename + GenFdsGlobalVariable.FdfFileTimeStamp = os.path.getmtime(FdfFilename) + + if (Options.activePlatform): + ActivePlatform = Options.activePlatform + ActivePlatform = GenFdsGlobalVariable.ReplaceWorkspaceMacro(ActivePlatform) + + if ActivePlatform[0:2] == '..': + ActivePlatform = os.path.realpath(ActivePlatform) + + if ActivePlatform[1] != ':': + ActivePlatform = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, ActivePlatform) + + if not os.path.exists(ActivePlatform) : + EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, "ActivePlatform doesn't exist!") + + if ActivePlatform.find(Workspace) == -1: + EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, "ActivePlatform doesn't exist in Workspace!") + + ActivePlatform = ActivePlatform.replace(Workspace, '') + if len(ActivePlatform) > 0 : + if ActivePlatform[0] == '\\' or ActivePlatform[0] == '/': + ActivePlatform = ActivePlatform[1:] + else: + EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, "ActivePlatform doesn't exist!") + else : + EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing active platform") + + GenFdsGlobalVariable.ActivePlatform = PathClass(NormPath(ActivePlatform), Workspace) + + BuildConfigurationFile = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, "Conf/target.txt")) + if os.path.isfile(BuildConfigurationFile) == True: + TargetTxtClassObject.TargetTxtClassObject(BuildConfigurationFile) + else: + EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, ExtraData=BuildConfigurationFile) + + if Options.Macros: + for Pair in Options.Macros: + Pair.strip('"') + List = Pair.split('=') + if len(List) == 2: + FdfParser.InputMacroDict[List[0].strip()] = List[1].strip() + if List[0].strip() == "EFI_SOURCE": + GlobalData.gEfiSource = List[1].strip() + elif List[0].strip() == "EDK_SOURCE": + GlobalData.gEdkSource = List[1].strip() + else: + GlobalData.gEdkGlobal[List[0].strip()] = List[1].strip() + else: + FdfParser.InputMacroDict[List[0].strip()] = None + + """call Workspace build create database""" + os.environ["WORKSPACE"] = Workspace + BuildWorkSpace = WorkspaceDatabase(':memory:', GlobalData.gGlobalDefines) + BuildWorkSpace.InitDatabase() + + # + # Get files real name in workspace dir + # + GlobalData.gAllFiles = DirCache(Workspace) + GlobalData.gWorkspace = Workspace + + if (Options.archList) : + ArchList = Options.archList.split(',') + else: +# EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing build ARCH") + ArchList = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON'].SupArchList + + TargetArchList = set(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON'].SupArchList) & set(ArchList) + if len(TargetArchList) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, "Target ARCH %s not in platform supported ARCH %s" % (str(ArchList), str(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON'].SupArchList))) + + for Arch in ArchList: + GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = NormPath(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].OutputDirectory) + + if (Options.outputDir): + OutputDirFromCommandLine = GenFdsGlobalVariable.ReplaceWorkspaceMacro(Options.outputDir) + for Arch in ArchList: + GenFdsGlobalVariable.OutputDirDict[Arch] = OutputDirFromCommandLine + else: + for Arch in ArchList: + GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.join(GenFdsGlobalVariable.OutputDirFromDscDict[Arch], GenFdsGlobalVariable.TargetName + '_' + GenFdsGlobalVariable.ToolChainTag) + + for Key in GenFdsGlobalVariable.OutputDirDict: + OutputDir = GenFdsGlobalVariable.OutputDirDict[Key] + if OutputDir[0:2] == '..': + OutputDir = os.path.realpath(OutputDir) + + if OutputDir[1] != ':': + OutputDir = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, OutputDir) + + if not os.path.exists(OutputDir): + EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, ExtraData=OutputDir) + GenFdsGlobalVariable.OutputDirDict[Key] = OutputDir + + """ Parse Fdf file, has to place after build Workspace as FDF may contain macros from DSC file """ + FdfParserObj = FdfParser.FdfParser(FdfFilename) + FdfParserObj.ParseFile() + + if FdfParserObj.CycleReferenceCheck(): + EdkLogger.error("GenFds", BuildToolError.FORMAT_NOT_SUPPORTED, "Cycle Reference Detected in FDF file") + + if (Options.uiFdName) : + if Options.uiFdName.upper() in FdfParserObj.Profile.FdDict.keys(): + GenFds.OnlyGenerateThisFd = Options.uiFdName + else: + EdkLogger.error("GenFds", BuildToolError.OPTION_VALUE_INVALID, + "No such an FD in FDF file: %s" % Options.uiFdName) + + if (Options.uiFvName) : + if Options.uiFvName.upper() in FdfParserObj.Profile.FvDict.keys(): + GenFds.OnlyGenerateThisFv = Options.uiFvName + else: + EdkLogger.error("GenFds", BuildToolError.OPTION_VALUE_INVALID, + "No such an FV in FDF file: %s" % Options.uiFvName) + + """Modify images from build output if the feature of loading driver at fixed address is on.""" + if GenFdsGlobalVariable.FixedLoadAddress: + GenFds.PreprocessImage(BuildWorkSpace, GenFdsGlobalVariable.ActivePlatform) + """Call GenFds""" + GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList) + + """Display FV space info.""" + GenFds.DisplayFvSpaceInfo(FdfParserObj) + + except FdfParser.Warning, X: + EdkLogger.error(X.ToolName, BuildToolError.FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError = False) + ReturnCode = BuildToolError.FORMAT_INVALID + except FatalError, X: + if Options.debug != None: + import traceback + EdkLogger.quiet(traceback.format_exc()) + ReturnCode = X.args[0] + except: + import traceback + EdkLogger.error( + "\nPython", + CODE_ERROR, + "Tools code failure", + ExtraData="Please submit bug report in www.TianoCore.org, attaching following call stack trace!\n", + RaiseError=False + ) + EdkLogger.quiet(traceback.format_exc()) + ReturnCode = CODE_ERROR + return ReturnCode + +gParamCheck = [] +def SingleCheckCallback(option, opt_str, value, parser): + if option not in gParamCheck: + setattr(parser.values, option.dest, value) + gParamCheck.append(option) + else: + parser.error("Option %s only allows one instance in command line!" % option) + +## 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(): + usage = "%prog [options] -f input_file -a arch_list -b build_target -p active_platform -t tool_chain_tag -D \"MacroName [= MacroValue]\"" + Parser = OptionParser(usage=usage,description=__copyright__,version="%prog " + str(versionNumber)) + Parser.add_option("-f", "--file", dest="filename", type="string", help="Name of FDF file to convert", action="callback", callback=SingleCheckCallback) + Parser.add_option("-a", "--arch", dest="archList", help="comma separated list containing one or more of: IA32, X64, IPF, ARM or EBC which should be built, overrides target.txt?s TARGET_ARCH") + Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.") + Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed.") + Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.") + Parser.add_option("-p", "--platform", type="string", dest="activePlatform", help="Set the ACTIVE_PLATFORM, overrides target.txt ACTIVE_PLATFORM setting.", + action="callback", callback=SingleCheckCallback) + Parser.add_option("-w", "--workspace", type="string", dest="Workspace", default=os.environ.get('WORKSPACE'), help="Set the WORKSPACE", + action="callback", callback=SingleCheckCallback) + 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("-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.", + action="callback", callback=SingleCheckCallback) + Parser.add_option("-D", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".") + Parser.add_option("-s", "--specifyaddress", dest="FixedAddress", action="store_true", type=None, help="Specify driver load address.") + (Options, args) = Parser.parse_args() + return Options + +## The class implementing the EDK2 flash image generation process +# +# This process includes: +# 1. Collect workspace information, includes platform and module information +# 2. Call methods of Fd class to generate FD +# 3. Call methods of Fv class to generate FV that not belong to FD +# +class GenFds : + FdfParsef = None + # FvName in FDF, FvBinFile name + FvBinDict = {} + OnlyGenerateThisFd = None + OnlyGenerateThisFv = None + + ## GenFd() + # + # @param OutputDir Output directory + # @param FdfParser FDF contents parser + # @param Workspace The directory of workspace + # @param ArchList The Arch list of platform + # + def GenFd (OutputDir, FdfParser, WorkSpace, ArchList): + GenFdsGlobalVariable.SetDir ('', FdfParser, WorkSpace, ArchList) + + GenFdsGlobalVariable.VerboseLogger(" Gen Fd !") + 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(GenFds.FvBinDict) + elif GenFds.OnlyGenerateThisFv == None: + for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys(): + FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName] + FdObj.GenFd(GenFds.FvBinDict) + + GenFdsGlobalVariable.VerboseLogger(" Gen FV ! ") + if GenFds.OnlyGenerateThisFv != None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys(): + FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(GenFds.OnlyGenerateThisFv.upper()) + if FvObj != None: + Buffer = StringIO.StringIO() + # Get FV base Address + FvObj.AddToBuffer(Buffer, None, GenFds.GetFvBlockSize(FvObj)) + Buffer.close() + return + elif GenFds.OnlyGenerateThisFd == None: + for FvName in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys(): + Buffer = StringIO.StringIO('') + FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[FvName] + # Get FV base Address + FvObj.AddToBuffer(Buffer, None, GenFds.GetFvBlockSize(FvObj)) + Buffer.close() + + if GenFds.OnlyGenerateThisFv == None and GenFds.OnlyGenerateThisFd == None: + GenFdsGlobalVariable.VerboseLogger(" Gen Capsule !") + for CapsuleObj in GenFdsGlobalVariable.FdfParser.Profile.CapsuleList: + CapsuleObj.GenCapsule() + + if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}: + GenFdsGlobalVariable.VerboseLogger(" Gen Option ROM !") + for DriverName in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.keys(): + OptRomObj = GenFdsGlobalVariable.FdfParser.Profile.OptRomDict[DriverName] + OptRomObj.AddToBuffer(None) + + ## GetFvBlockSize() + # + # @param FvObj Whose block size to get + # @retval int Block size value + # + def GetFvBlockSize(FvObj): + DefaultBlockSize = 0x10000 + FdObj = None + if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys(): + FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()] + if FdObj == None: + for ElementFd in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values(): + for ElementRegion in ElementFd.RegionList: + if ElementRegion.RegionType == 'FV': + for ElementRegionData in ElementRegion.RegionDataList: + if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName: + if FvObj.BlockSizeList != []: + return FvObj.BlockSizeList[0][0] + else: + return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList) + if FvObj.BlockSizeList != []: + return FvObj.BlockSizeList[0][0] + return DefaultBlockSize + else: + for ElementRegion in FdObj.RegionList: + if ElementRegion.RegionType == 'FV': + for ElementRegionData in ElementRegion.RegionDataList: + if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName: + if FvObj.BlockSizeList != []: + return FvObj.BlockSizeList[0][0] + else: + return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList) + return DefaultBlockSize + + ## DisplayFvSpaceInfo() + # + # @param FvObj Whose block size to get + # @retval None + # + def DisplayFvSpaceInfo(FdfParser): + + FvSpaceInfoList = [] + MaxFvNameLength = 0 + for FvName in FdfParser.Profile.FvDict: + if len(FvName) > MaxFvNameLength: + MaxFvNameLength = len(FvName) + FvSpaceInfoFileName = os.path.join(GenFdsGlobalVariable.FvDir, FvName.upper() + '.Fv.map') + if os.path.exists(FvSpaceInfoFileName): + FileLinesList = linecache.getlines(FvSpaceInfoFileName) + TotalFound = False + Total = '' + UsedFound = False + Used = '' + FreeFound = False + Free = '' + for Line in FileLinesList: + NameValue = Line.split('=') + if len(NameValue) == 2: + if NameValue[0].strip() == 'EFI_FV_TOTAL_SIZE': + TotalFound = True + Total = NameValue[1].strip() + if NameValue[0].strip() == 'EFI_FV_TAKEN_SIZE': + UsedFound = True + Used = NameValue[1].strip() + if NameValue[0].strip() == 'EFI_FV_SPACE_SIZE': + FreeFound = True + Free = NameValue[1].strip() + + if TotalFound and UsedFound and FreeFound: + FvSpaceInfoList.append((FvName, Total, Used, Free)) + + GenFdsGlobalVariable.InfLogger('\nFV Space Information') + for FvSpaceInfo in FvSpaceInfoList: + Name = FvSpaceInfo[0] + TotalSizeValue = long(FvSpaceInfo[1], 0) + UsedSizeValue = long(FvSpaceInfo[2], 0) + FreeSizeValue = long(FvSpaceInfo[3], 0) + GenFdsGlobalVariable.InfLogger(Name + ' ' + '[' + str((UsedSizeValue+0.0)/TotalSizeValue)[0:4].lstrip('0.') + '%Full] ' + str(TotalSizeValue) + ' total, ' + str(UsedSizeValue) + ' used, ' + str(FreeSizeValue) + ' free') + + ## PreprocessImage() + # + # @param BuildDb Database from build meta data files + # @param DscFile modules from dsc file will be preprocessed + # @retval None + # + def PreprocessImage(BuildDb, DscFile): + PcdDict = BuildDb.BuildObject[DscFile, 'COMMON'].Pcds + PcdValue = '' + for Key in PcdDict: + PcdObj = PcdDict[Key] + if PcdObj.TokenCName == 'PcdBsBaseAddress': + PcdValue = PcdObj.DefaultValue + break + + if PcdValue == '': + return + + Int64PcdValue = long(PcdValue, 0) + if Int64PcdValue == 0 or Int64PcdValue < -1: + return + + TopAddress = 0 + if Int64PcdValue > 0: + TopAddress = Int64PcdValue + + ModuleDict = BuildDb.BuildObject[DscFile, 'COMMON'].Modules + for Key in ModuleDict: + ModuleObj = BuildDb.BuildObject[Key, 'COMMON'] + print ModuleObj.BaseName + ' ' + ModuleObj.ModuleType + + ##Define GenFd as static function + GenFd = staticmethod(GenFd) + GetFvBlockSize = staticmethod(GetFvBlockSize) + DisplayFvSpaceInfo = staticmethod(DisplayFvSpaceInfo) + PreprocessImage = staticmethod(PreprocessImage) + +if __name__ == '__main__': + r = main() + ## 0-127 is a safe return range, and 1 is a standard default error + if r < 0 or r > 127: r = 1 + sys.exit(r) + diff --git a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py new file mode 100644 index 0000000000..d556ce7ade --- /dev/null +++ b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py @@ -0,0 +1,472 @@ +## @file +# Global variables for GenFds +# +# Copyright (c) 2007, 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 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 subprocess +import struct +import array + +from Common.BuildToolError import * +from Common import EdkLogger +from Common.Misc import SaveFileOnChange + +## Global variables +# +# +class GenFdsGlobalVariable: + FvDir = '' + OutputDirDict = {} + BinDir = '' + # will be FvDir + os.sep + 'Ffs' + FfsDir = '' + FdfParser = None + LibDir = '' + WorkSpace = None + WorkSpaceDir = '' + EdkSourceDir = '' + OutputDirFromDscDict = {} + TargetName = '' + ToolChainTag = '' + RuleDict = {} + ArchList = None + VtfDict = {} + ActivePlatform = None + FvAddressFileName = '' + VerboseMode = False + DebugLevel = -1 + SharpCounter = 0 + SharpNumberPerLine = 40 + FdfFile = '' + FdfFileTimeStamp = 0 + FixedLoadAddress = False + + SectionHeader = struct.Struct("3B 1B") + + ## SetDir() + # + # @param OutputDir Output directory + # @param FdfParser FDF contents parser + # @param Workspace The directory of workspace + # @param ArchList The Arch list of platform + # + def SetDir (OutputDir, FdfParser, WorkSpace, ArchList): + GenFdsGlobalVariable.VerboseLogger( "GenFdsGlobalVariable.OutputDir :%s" %OutputDir) +# GenFdsGlobalVariable.OutputDirDict = OutputDir + GenFdsGlobalVariable.FdfParser = FdfParser + GenFdsGlobalVariable.WorkSpace = WorkSpace + GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], 'FV') + if not os.path.exists(GenFdsGlobalVariable.FvDir) : + os.makedirs(GenFdsGlobalVariable.FvDir) + GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs') + if not os.path.exists(GenFdsGlobalVariable.FfsDir) : + os.makedirs(GenFdsGlobalVariable.FfsDir) + if ArchList != None: + GenFdsGlobalVariable.ArchList = ArchList + + T_CHAR_LF = '\n' + # + # Create FV Address inf file + # + GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf') + FvAddressFile = open (GenFdsGlobalVariable.FvAddressFileName, 'w') + # + # Add [Options] + # + FvAddressFile.writelines("[options]" + T_CHAR_LF) + BsAddress = '0' + for Arch in ArchList: + if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].BsBaseAddress: + BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].BsBaseAddress + break + + FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \ + BsAddress + \ + T_CHAR_LF) + + RtAddress = '0' + for Arch in ArchList: + if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].RtBaseAddress: + RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].RtBaseAddress + + FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \ + RtAddress + \ + T_CHAR_LF) + + FvAddressFile.close() + + ## ReplaceWorkspaceMacro() + # + # @param String String that may contain macro + # + def ReplaceWorkspaceMacro(String): + Str = String.replace('$(WORKSPACE)', GenFdsGlobalVariable.WorkSpaceDir) + if os.path.exists(Str): + if not os.path.isabs(Str): + Str = os.path.abspath(Str) + else: + Str = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, String) + return os.path.normpath(Str) + + ## Check if the input files are newer than output files + # + # @param Output Path of output file + # @param Input Path list of input files + # + # @retval True if Output doesn't exist, or any Input is newer + # @retval False if all Input is older than Output + # + @staticmethod + def NeedsUpdate(Output, Input): + if not os.path.exists(Output): + return True + # always update "Output" if no "Input" given + if Input == None or len(Input) == 0: + return True + + # if fdf file is changed after the 'Output" is generated, update the 'Output' + OutputTime = os.path.getmtime(Output) + if GenFdsGlobalVariable.FdfFileTimeStamp > OutputTime: + return True + + for F in Input: + # always update "Output" if any "Input" doesn't exist + if not os.path.exists(F): + return True + # always update "Output" if any "Input" is newer than "Output" + if os.path.getmtime(F) > OutputTime: + return True + return False + + @staticmethod + def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None, + GuidHdrLen=None, GuidAttr=None, Ui=None, Ver=None): + if not GenFdsGlobalVariable.NeedsUpdate(Output, Input): + return + GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) + + Cmd = ["GenSec"] + if Type not in [None, '']: + Cmd += ["-s", Type] + if CompressionType not in [None, '']: + Cmd += ["-c", CompressionType] + if Guid != None: + Cmd += ["-g", Guid] + if GuidHdrLen not in [None, '']: + Cmd += ["-l", GuidHdrLen] + if GuidAttr not in [None, '']: + Cmd += ["-r", GuidAttr] + + if Ui not in [None, '']: + #Cmd += ["-n", '"' + Ui + '"'] + SectionData = array.array('B', [0,0,0,0]) + SectionData.fromstring(Ui.encode("utf_16_le")) + SectionData.append(0) + SectionData.append(0) + Len = len(SectionData) + GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x15) + SaveFileOnChange(Output, SectionData.tostring()) + elif Ver not in [None, '']: + #Cmd += ["-j", Ver] + SectionData = array.array('B', [0,0,0,0]) + SectionData.fromstring(Ver.encode("utf_16_le")) + SectionData.append(0) + SectionData.append(0) + Len = len(SectionData) + GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x14) + SaveFileOnChange(Output, SectionData.tostring()) + else: + Cmd += ["-o", Output] + Cmd += Input + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section") + + @staticmethod + def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None, + SectionAlign=None): + if not GenFdsGlobalVariable.NeedsUpdate(Output, Input): + return + GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) + + Cmd = ["GenFfs", "-t", Type, "-g", Guid] + if Fixed == True: + Cmd += ["-x"] + if CheckSum: + Cmd += ["-s"] + if Align not in [None, '']: + Cmd += ["-a", Align] + + Cmd += ["-o", Output] + for I in range(0, len(Input)): + Cmd += ("-i", Input[I]) + if SectionAlign not in [None, '', []] and SectionAlign[I] not in [None, '']: + Cmd += ("-n", SectionAlign[I]) + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS") + + @staticmethod + def GenerateFirmwareVolume(Output, Input, BaseAddress=None, Capsule=False, Dump=False, + AddressFile=None, MapFile=None, FfsList=[]): + if not GenFdsGlobalVariable.NeedsUpdate(Output, Input+FfsList): + return + GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) + + Cmd = ["GenFv"] + if BaseAddress not in [None, '']: + Cmd += ["-r", BaseAddress] + if Capsule: + Cmd += ["-c"] + if Dump: + Cmd += ["-p"] + if AddressFile not in [None, '']: + Cmd += ["-a", AddressFile] + if MapFile not in [None, '']: + Cmd += ["-m", MapFile] + Cmd += ["-o", Output] + for I in Input: + Cmd += ["-i", I] + + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV") + + @staticmethod + def GenerateVtf(Output, Input, BaseAddress=None, FvSize=None): + if not GenFdsGlobalVariable.NeedsUpdate(Output, Input): + return + GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) + + Cmd = ["GenVtf"] + if BaseAddress not in [None, ''] and FvSize not in [None, ''] \ + and len(BaseAddress) == len(FvSize): + for I in range(0, len(BaseAddress)): + Cmd += ["-r", BaseAddress[I], "-s", FvSize[I]] + Cmd += ["-o", Output] + for F in Input: + Cmd += ["-f", F] + + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate VTF") + + @staticmethod + def GenerateFirmwareImage(Output, Input, Type="efi", SubType=None, Zero=False, + Strip=False, Replace=False, TimeStamp=None, Join=False, + Align=None, Padding=None, Convert=False): + if not GenFdsGlobalVariable.NeedsUpdate(Output, Input): + return + GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) + + Cmd = ["GenFw"] + if Type.lower() == "te": + Cmd += ["-t"] + if SubType not in [None, '']: + Cmd += ["-e", SubType] + if TimeStamp not in [None, '']: + Cmd += ["-s", TimeStamp] + if Align not in [None, '']: + Cmd += ["-a", Align] + if Padding not in [None, '']: + Cmd += ["-p", Padding] + if Zero: + Cmd += ["-z"] + if Strip: + Cmd += ["-l"] + if Replace: + Cmd += ["-r"] + if Join: + Cmd += ["-j"] + if Convert: + Cmd += ["-m"] + Cmd += ["-o", Output] + Cmd += Input + + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image") + + @staticmethod + def GenerateOptionRom(Output, EfiInput, BinaryInput, Compress=False, ClassCode=None, + Revision=None, DeviceId=None, VendorId=None): +# if not GenFdsGlobalVariable.NeedsUpdate(Output, Input): +# return +# GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) + + Cmd = ["EfiRom"] + if len(EfiInput) > 0: + + if Compress: + Cmd += ["-ec"] + else: + Cmd += ["-e"] + + for EfiFile in EfiInput: + Cmd += [EfiFile] + + if len(BinaryInput) > 0: + Cmd += ["-b"] + for BinFile in BinaryInput: + Cmd += [BinFile] + + if ClassCode != None: + Cmd += ["-l", ClassCode] + if Revision != None: + Cmd += ["-r", Revision] + if DeviceId != None: + Cmd += ["-i", DeviceId] + if VendorId != None: + Cmd += ["-f", VendorId] + + Cmd += ["-o", Output] + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom") + + @staticmethod + def GuidTool(Output, Input, ToolPath, Options=''): + if not GenFdsGlobalVariable.NeedsUpdate(Output, Input): + return + GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) + + Cmd = [ToolPath, Options] + Cmd += ["-o", Output] + Cmd += Input + + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath) + + def CallExternalTool (cmd, errorMess): + + if type(cmd) not in (tuple, list): + GenFdsGlobalVariable.ErrorLogger("ToolError! Invalid parameter type in call to CallExternalTool") + + if GenFdsGlobalVariable.DebugLevel != -1: + cmd += ('--debug', str(GenFdsGlobalVariable.DebugLevel)) + GenFdsGlobalVariable.InfLogger (cmd) + + if GenFdsGlobalVariable.VerboseMode: + cmd += ('-v',) + GenFdsGlobalVariable.InfLogger (cmd) + else: + sys.stdout.write ('#') + sys.stdout.flush() + GenFdsGlobalVariable.SharpCounter = GenFdsGlobalVariable.SharpCounter + 1 + if GenFdsGlobalVariable.SharpCounter % GenFdsGlobalVariable.SharpNumberPerLine == 0: + sys.stdout.write('\n') + + try: + PopenObject = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr= subprocess.PIPE) + except Exception, X: + EdkLogger.error("GenFds", BuildToolError.COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0])) + (out, error) = PopenObject.communicate() + + while PopenObject.returncode == None : + PopenObject.wait() + if PopenObject.returncode != 0 or GenFdsGlobalVariable.VerboseMode or GenFdsGlobalVariable.DebugLevel != -1: + GenFdsGlobalVariable.InfLogger ("Return Value = %d" %PopenObject.returncode) + GenFdsGlobalVariable.InfLogger (out) + GenFdsGlobalVariable.InfLogger (error) + if PopenObject.returncode != 0: + print "###", cmd + EdkLogger.error("GenFds", BuildToolError.COMMAND_FAILURE, errorMess) + + def VerboseLogger (msg): + EdkLogger.verbose(msg) + + def InfLogger (msg): + EdkLogger.info(msg) + + def ErrorLogger (msg, File = None, Line = None, ExtraData = None): + EdkLogger.error('GenFds', BuildToolError.GENFDS_ERROR, msg, File, Line, ExtraData) + + def DebugLogger (Level, msg): + EdkLogger.debug(Level, msg) + + ## ReplaceWorkspaceMacro() + # + # @param Str String that may contain macro + # @param MacroDict Dictionary that contains macro value pair + # + def MacroExtend (Str, MacroDict = {}, Arch = 'COMMON'): + if Str == None : + return None + + Dict = {'$(WORKSPACE)' : GenFdsGlobalVariable.WorkSpaceDir, + '$(EDK_SOURCE)' : GenFdsGlobalVariable.EdkSourceDir, +# '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc, + '$(TARGET)' : GenFdsGlobalVariable.TargetName, + '$(TOOL_CHAIN_TAG)' : GenFdsGlobalVariable.ToolChainTag + } + OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]] + if Arch != 'COMMON' and Arch in GenFdsGlobalVariable.ArchList: + OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch] + + Dict['$(OUTPUT_DIRECTORY)'] = OutputDir + + if MacroDict != None and len (MacroDict) != 0: + Dict.update(MacroDict) + + for key in Dict.keys(): + if Str.find(key) >= 0 : + Str = Str.replace (key, Dict[key]) + + if Str.find('$(ARCH)') >= 0: + if len(GenFdsGlobalVariable.ArchList) == 1: + Str = Str.replace('$(ARCH)', GenFdsGlobalVariable.ArchList[0]) + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "No way to determine $(ARCH) for %s" % Str) + + return Str + + ## GetPcdValue() + # + # @param PcdPattern pattern that labels a PCD. + # + def GetPcdValue (PcdPattern): + if PcdPattern == None : + return None + PcdPair = PcdPattern.lstrip('PCD(').rstrip(')').strip().split('.') + TokenSpace = PcdPair[0] + TokenCName = PcdPair[1] + + 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 + + for Package in GenFdsGlobalVariable.WorkSpace.PackageList: + PcdDict = Package.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 + + return PcdValue + + SetDir = staticmethod(SetDir) + ReplaceWorkspaceMacro = staticmethod(ReplaceWorkspaceMacro) + CallExternalTool = staticmethod(CallExternalTool) + VerboseLogger = staticmethod(VerboseLogger) + InfLogger = staticmethod(InfLogger) + ErrorLogger = staticmethod(ErrorLogger) + DebugLogger = staticmethod(DebugLogger) + MacroExtend = staticmethod (MacroExtend) + GetPcdValue = staticmethod(GetPcdValue) diff --git a/BaseTools/Source/Python/GenFds/GuidSection.py b/BaseTools/Source/Python/GenFds/GuidSection.py new file mode 100644 index 0000000000..e111e0fe50 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/GuidSection.py @@ -0,0 +1,190 @@ +## @file +# process GUIDed section generation +# +# Copyright (c) 2007, 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 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 Section +import subprocess +from Ffs import Ffs +import os +from GenFdsGlobalVariable import GenFdsGlobalVariable +from CommonDataClass.FdfClass import GuidSectionClassObject +from Common import ToolDefClassObject +import sys +from Common import EdkLogger +from Common.BuildToolError import * + +## generate GUIDed section +# +# +class GuidSection(GuidSectionClassObject) : + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + GuidSectionClassObject.__init__(self) + + ## GenSection() method + # + # Generate GUIDed section + # + # @param self The object pointer + # @param OutputPath Where to place output file + # @param ModuleName Which module this section belongs to + # @param SecNum Index of section + # @param KeyStringList Filter for inputs of section generation + # @param FfsInf FfsInfStatement object that contains this section data + # @param Dict dictionary contains macro and its value + # @retval tuple (Generated file name, section alignment) + # + def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}): + # + # Generate all section + # + self.KeyStringList = KeyStringList + self.CurrentArchList = GenFdsGlobalVariable.ArchList + if FfsInf != None: + self.Alignment = FfsInf.__ExtendMacro__(self.Alignment) + self.NameGuid = FfsInf.__ExtendMacro__(self.NameGuid) + self.SectionType = FfsInf.__ExtendMacro__(self.SectionType) + self.CurrentArchList = [FfsInf.CurrentArch] + + SectFile = tuple() + Index = 0 + for Sect in self.SectionList: + Index = Index + 1 + SecIndex = '%s.%d' %(SecNum,Index) + ReturnSectList, align = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList,FfsInf, Dict) + if ReturnSectList != []: + for file in ReturnSectList: + SectFile += (file,) + + + OutputFile = OutputPath + \ + os.sep + \ + ModuleName + \ + 'SEC' + \ + SecNum + \ + Ffs.SectionSuffix['GUIDED'] + OutputFile = os.path.normpath(OutputFile) + + ExternalTool = None + if self.NameGuid != None: + ExternalTool = self.__FindExtendTool__() + # + # If not have GUID , call default + # GENCRC32 section + # + if self.NameGuid == None : + GenFdsGlobalVariable.VerboseLogger( "Use GenSection function Generate CRC32 Section") + GenFdsGlobalVariable.GenerateSection(OutputFile, SectFile, Section.Section.SectionType[self.SectionType]) + OutputFileList = [] + OutputFileList.append(OutputFile) + return OutputFileList, self.Alignment + #or GUID not in External Tool List + elif ExternalTool == None: + EdkLogger.error("GenFds", GENFDS_ERROR, "No tool found with GUID %s" % self.NameGuid) + else: + # + # Call GenSection with DUMMY section type. + # + GenFdsGlobalVariable.GenerateSection(OutputFile+".dummy", SectFile) + # + # Use external tool process the Output + # + InputFile = OutputFile+".dummy" + TempFile = OutputPath + \ + os.sep + \ + ModuleName + \ + 'SEC' + \ + SecNum + \ + '.tmp' + TempFile = os.path.normpath(TempFile) + + ExternalToolCmd = ( + ExternalTool, + '-e', + '-o', TempFile, + InputFile, + ) + + # + # Call external tool + # + GenFdsGlobalVariable.GuidTool(TempFile, [InputFile], ExternalTool, '-e') + + # + # Call Gensection Add Secntion Header + # + Attribute = None + if self.ProcessRequired == True: + Attribute = 'PROCSSING_REQUIRED' + if self.AuthStatusValid == True: + Attribute = 'AUTH_STATUS_VALID' + GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'], + Guid=self.NameGuid, GuidAttr=Attribute) + OutputFileList = [] + OutputFileList.append(OutputFile) + return OutputFileList, self.Alignment + + ## __FindExtendTool() + # + # Find location of tools to process section data + # + # @param self The object pointer + # + def __FindExtendTool__(self): + # if user not specify filter, try to deduce it from global data. + if self.KeyStringList == None or self.KeyStringList == []: + Target = GenFdsGlobalVariable.TargetName + ToolChain = GenFdsGlobalVariable.ToolChainTag + ToolDb = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.WorkSpaceDir).ToolsDefTxtDatabase + if ToolChain not in ToolDb['TOOL_CHAIN_TAG']: + EdkLogger.error("GenFds", GENFDS_ERROR, "Can not find external tool because tool tag %s is not defined in tools_def.txt!" % ToolChain) + self.KeyStringList = [Target+'_'+ToolChain+'_'+self.CurrentArchList[0]] + for Arch in self.CurrentArchList: + if Target+'_'+ToolChain+'_'+Arch not in self.KeyStringList: + self.KeyStringList.append(Target+'_'+ToolChain+'_'+Arch) + + ToolDefinition = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.WorkSpaceDir).ToolsDefTxtDictionary + ToolPathTmp = None + for ToolDef in ToolDefinition.items(): + if self.NameGuid == ToolDef[1]: + KeyList = ToolDef[0].split('_') + Key = KeyList[0] + \ + '_' + \ + KeyList[1] + \ + '_' + \ + KeyList[2] + if Key in self.KeyStringList and KeyList[4] == 'GUID': + + ToolPath = ToolDefinition.get( Key + \ + '_' + \ + KeyList[3] + \ + '_' + \ + 'PATH') + if ToolPathTmp == None: + ToolPathTmp = ToolPath + else: + if ToolPathTmp != ToolPath: + EdkLogger.error("GenFds", GENFDS_ERROR, "Don't know which tool to use, %s or %s ?" % (ToolPathTmp, ToolPath)) + + + return ToolPathTmp + + + diff --git a/BaseTools/Source/Python/GenFds/OptRomFileStatement.py b/BaseTools/Source/Python/GenFds/OptRomFileStatement.py new file mode 100644 index 0000000000..c360c6d9ad --- /dev/null +++ b/BaseTools/Source/Python/GenFds/OptRomFileStatement.py @@ -0,0 +1,50 @@ +## @file +# process OptionROM generation from FILE statement +# +# Copyright (c) 2007, 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 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 + +from GenFdsGlobalVariable import GenFdsGlobalVariable +## +# +# +class OptRomFileStatement: + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + self.FileName = None + self.FileType = None + self.OverrideAttribs = None + + ## GenFfs() method + # + # Generate FFS + # + # @param self The object pointer + # @param Dict dictionary contains macro and value pair + # @retval string Generated FFS file name + # + def GenFfs(self, Dict = {}): + + if self.FileName != None: + self.FileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName) + + return self.FileName + + + diff --git a/BaseTools/Source/Python/GenFds/OptRomInfStatement.py b/BaseTools/Source/Python/GenFds/OptRomInfStatement.py new file mode 100644 index 0000000000..b9f0af54c9 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/OptRomInfStatement.py @@ -0,0 +1,147 @@ +## @file +# process OptionROM generation from INF statement +# +# Copyright (c) 2007, 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 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 RuleSimpleFile +import RuleComplexFile +import Section +import OptionRom +import Common.GlobalData as GlobalData + +from Common.DataType import * +from Common.String import * +from FfsInfStatement import FfsInfStatement +from GenFdsGlobalVariable import GenFdsGlobalVariable + +## +# +# +class OptRomInfStatement (FfsInfStatement): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + FfsInfStatement.__init__(self) + self.OverrideAttribs = None + + ## __GetOptRomParams() method + # + # Parse inf file to get option ROM related parameters + # + # @param self The object pointer + # + def __GetOptRomParams(self): + + if self.OverrideAttribs == None: + self.OverrideAttribs = OptionRom.OverrideAttribs() + + if self.OverrideAttribs.PciVendorId == None: + self.OverrideAttribs.PciVendorId = self.OptRomDefs.get ('PCI_VENDOR_ID') + + if self.OverrideAttribs.PciClassCode == None: + self.OverrideAttribs.PciClassCode = self.OptRomDefs.get ('PCI_CLASS_CODE') + + if self.OverrideAttribs.PciDeviceId == None: + self.OverrideAttribs.PciDeviceId = self.OptRomDefs.get ('PCI_DEVICE_ID') + + if self.OverrideAttribs.PciRevision == None: + self.OverrideAttribs.PciRevision = self.OptRomDefs.get ('PCI_REVISION') + +# InfObj = GenFdsGlobalVariable.WorkSpace.BuildObject[self.PathClassObj, self.CurrentArch] +# RecordList = InfObj._RawData[MODEL_META_DATA_HEADER, InfObj._Arch, InfObj._Platform] +# for Record in RecordList: +# Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False) +# Name = Record[0] + ## GenFfs() method + # + # Generate FFS + # + # @param self The object pointer + # @retval string Generated .efi file name + # + def GenFfs(self): + # + # Parse Inf file get Module related information + # + + self.__InfParse__() + self.__GetOptRomParams() + # + # Get the rule of how to generate Ffs file + # + Rule = self.__GetRule__() + GenFdsGlobalVariable.VerboseLogger( "Packing binaries from inf file : %s" %self.InfFileName) + #FileType = Ffs.Ffs.ModuleTypeToFileType[Rule.ModuleType] + # + # For the rule only has simpleFile + # + if isinstance (Rule, RuleSimpleFile.RuleSimpleFile) : + EfiOutputList = self.__GenSimpleFileSection__(Rule) + return EfiOutputList + # + # For Rule has ComplexFile + # + elif isinstance(Rule, RuleComplexFile.RuleComplexFile): + EfiOutputList = self.__GenComplexFileSection__(Rule) + return EfiOutputList + + ## __GenSimpleFileSection__() method + # + # Get .efi files according to simple rule. + # + # @param self The object pointer + # @param Rule The rule object used to generate section + # @retval string File name of the generated section file + # + def __GenSimpleFileSection__(self, Rule): + # + # Prepare the parameter of GenSection + # + + OutputFileList = [] + if Rule.FileName != None: + GenSecInputFile = self.__ExtendMacro__(Rule.FileName) + OutputFileList.append(GenSecInputFile) + else: + OutputFileList, IsSect = Section.Section.GetFileList(self, '', Rule.FileExtension) + + return OutputFileList + + + ## __GenComplexFileSection__() method + # + # Get .efi by sections in complex Rule + # + # @param self The object pointer + # @param Rule The rule object used to generate section + # @retval string File name of the generated section file + # + def __GenComplexFileSection__(self, Rule): + + OutputFileList = [] + for Sect in Rule.SectionList: + if Sect.SectionType == 'PE32': + if Sect.FileName != None: + GenSecInputFile = self.__ExtendMacro__(Sect.FileName) + OutputFileList.append(GenSecInputFile) + else: + FileList, IsSect = Section.Section.GetFileList(self, '', Sect.FileExtension) + OutputFileList.extend(FileList) + + return OutputFileList + + \ No newline at end of file diff --git a/BaseTools/Source/Python/GenFds/OptionRom.py b/BaseTools/Source/Python/GenFds/OptionRom.py new file mode 100644 index 0000000000..e102e65f1c --- /dev/null +++ b/BaseTools/Source/Python/GenFds/OptionRom.py @@ -0,0 +1,140 @@ +## @file +# process OptionROM generation +# +# Copyright (c) 2007, 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 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 shutil +import subprocess +import StringIO + +import OptRomInfStatement +from GenFdsGlobalVariable import GenFdsGlobalVariable +from GenFds import GenFds +from CommonDataClass.FdfClass import OptionRomClassObject +from Common.Misc import SaveFileOnChange +from Common import EdkLogger +from Common.BuildToolError import * + +T_CHAR_LF = '\n' + +## +# +# +class OPTIONROM (OptionRomClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + OptionRomClassObject.__init__(self) + + + ## AddToBuffer() + # + # Generate Option ROM + # + # @param self The object pointer + # @param Buffer The buffer generated OptROM data will be put + # @retval string Generated OptROM file path + # + def AddToBuffer (self, Buffer) : + + GenFdsGlobalVariable.InfLogger( "\nGenerating %s Option ROM ..." %self.DriverName) + + EfiFileList = [] + BinFileList = [] + + # Process Modules in FfsList + for FfsFile in self.FfsList : + + if isinstance(FfsFile, OptRomInfStatement.OptRomInfStatement): + FilePathNameList = FfsFile.GenFfs() + if len(FilePathNameList) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s not produce .efi files, so NO file could be put into option ROM." % (FfsFile.InfFileName)) + if FfsFile.OverrideAttribs == None: + EfiFileList.extend(FilePathNameList) + else: + FileName = os.path.basename(FilePathNameList[0]) + TmpOutputDir = os.path.join(GenFdsGlobalVariable.FvDir, self.DriverName) + if not os.path.exists(TmpOutputDir) : + os.makedirs(TmpOutputDir) + TmpOutputFile = os.path.join(TmpOutputDir, FileName+'.tmp') + + GenFdsGlobalVariable.GenerateOptionRom(TmpOutputFile, + FilePathNameList, + [], + FfsFile.OverrideAttribs.NeedCompress, + FfsFile.OverrideAttribs.PciClassCode, + FfsFile.OverrideAttribs.PciRevision, + FfsFile.OverrideAttribs.PciDeviceId, + FfsFile.OverrideAttribs.PciVendorId) + BinFileList.append(TmpOutputFile) + else: + FilePathName = FfsFile.GenFfs() + if FfsFile.OverrideAttribs != None: + FileName = os.path.basename(FilePathName) + TmpOutputDir = os.path.join(GenFdsGlobalVariable.FvDir, self.DriverName) + if not os.path.exists(TmpOutputDir) : + os.makedirs(TmpOutputDir) + TmpOutputFile = os.path.join(TmpOutputDir, FileName+'.tmp') + + GenFdsGlobalVariable.GenerateOptionRom(TmpOutputFile, + [FilePathName], + [], + FfsFile.OverrideAttribs.NeedCompress, + FfsFile.OverrideAttribs.PciClassCode, + FfsFile.OverrideAttribs.PciRevision, + FfsFile.OverrideAttribs.PciDeviceId, + FfsFile.OverrideAttribs.PciVendorId) + BinFileList.append(TmpOutputFile) + else: + if FfsFile.FileType == 'EFI': + EfiFileList.append(FilePathName) + else: + BinFileList.append(FilePathName) + + # + # Call EfiRom tool + # + OutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.DriverName) + OutputFile = OutputFile + '.rom' + + GenFdsGlobalVariable.GenerateOptionRom( + OutputFile, + EfiFileList, + BinFileList + ) + + GenFdsGlobalVariable.InfLogger( "\nGenerate %s Option ROM Successfully" %self.DriverName) + GenFdsGlobalVariable.SharpCounter = 0 + + return OutputFile + +class OverrideAttribs: + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + + self.PciVendorId = None + self.PciClassCode = None + self.PciDeviceId = None + self.PciRevision = None + self.NeedCompress = False + + \ No newline at end of file diff --git a/BaseTools/Source/Python/GenFds/Region.py b/BaseTools/Source/Python/GenFds/Region.py new file mode 100644 index 0000000000..ed16c6fa98 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/Region.py @@ -0,0 +1,240 @@ +## @file +# process FD Region generation +# +# Copyright (c) 2007, 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 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 +# +from struct import * +from GenFdsGlobalVariable import GenFdsGlobalVariable +import StringIO +from CommonDataClass.FdfClass import RegionClassObject +import os +from Common import EdkLogger +from Common.BuildToolError import * + + +## generate Region +# +# +class Region(RegionClassObject): + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + RegionClassObject.__init__(self) + + + ## AddToBuffer() + # + # Add region data to the Buffer + # + # @param self The object pointer + # @param Buffer The buffer generated region data will be put + # @param BaseAddress base address of region + # @param BlockSize block size of region + # @param BlockNum How many blocks in region + # @param ErasePolarity Flash erase polarity + # @param VtfDict VTF objects + # @param MacroDict macro value pair + # @retval string Generated FV file path + # + + def AddToBuffer(self, Buffer, BaseAddress, BlockSizeList, ErasePolarity, FvBinDict, vtfDict = None, MacroDict = {}): + Size = self.Size + GenFdsGlobalVariable.InfLogger('Generate Region at Offset 0x%X' % self.Offset) + GenFdsGlobalVariable.InfLogger(" Region Size = 0x%X" %Size) + GenFdsGlobalVariable.SharpCounter = 0 + + if self.RegionType == 'FV': + # + # Get Fv from FvDict + # + FvBuffer = StringIO.StringIO('') + RegionBlockSize = self.BlockSizeOfRegion(BlockSizeList) + RegionBlockNum = self.BlockNumOfRegion(RegionBlockSize) + + self.FvAddress = int(BaseAddress, 16) + self.Offset + FvBaseAddress = '0x%X' %self.FvAddress + + for RegionData in self.RegionDataList: + + if RegionData.endswith(".fv"): + RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict) + GenFdsGlobalVariable.InfLogger(' Region FV File Name = .fv : %s'%RegionData) + if RegionData[1] != ':' : + RegionData = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData) + if not os.path.exists(RegionData): + EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData) + + BinFile = open (RegionData, 'r+b') + FvBuffer.write(BinFile.read()) + if FvBuffer.len > Size: + EdkLogger.error("GenFds", GENFDS_ERROR, + "Size of FV File (%s) is larger than Region Size 0x%X specified." \ + % (RegionData, Size)) + break + + if RegionData.upper() in FvBinDict.keys(): + continue + + FvObj = None + if RegionData.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys(): + FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(RegionData.upper()) + + if FvObj != None : + GenFdsGlobalVariable.InfLogger(' Region Name = FV') + # + # Call GenFv tool + # + BlockSize = RegionBlockSize + BlockNum = RegionBlockNum + if FvObj.BlockSizeList != []: + if FvObj.BlockSizeList[0][0] != None: + BlockSize = FvObj.BlockSizeList[0][0] + if FvObj.BlockSizeList[0][1] != None: + BlockNum = FvObj.BlockSizeList[0][1] + self.FvAddress = self.FvAddress + FvBuffer.len + FvAlignValue = self.GetFvAlignValue(FvObj.FvAlignment) + if self.FvAddress % FvAlignValue != 0: + EdkLogger.error("GenFds", GENFDS_ERROR, + "FV (%s) is NOT %s Aligned!" % (FvObj.UiFvName, FvObj.FvAlignment)) + FvBaseAddress = '0x%X' %self.FvAddress + FileName = FvObj.AddToBuffer(FvBuffer, FvBaseAddress, BlockSize, BlockNum, ErasePolarity, vtfDict) + + if FvBuffer.len > Size: + EdkLogger.error("GenFds", GENFDS_ERROR, + "Size of FV (%s) is larger than Region Size 0x%X specified." % (RegionData, Size)) + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (RegionData)) + + + if FvBuffer.len > 0: + Buffer.write(FvBuffer.getvalue()) + else: + BinFile = open (FileName, 'rb') + Buffer.write(BinFile.read()) + + FvBuffer.close() + + if self.RegionType == 'FILE': + FvBuffer = StringIO.StringIO('') + for RegionData in self.RegionDataList: + RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict) + GenFdsGlobalVariable.InfLogger(' Region File Name = FILE: %s'%RegionData) + if RegionData[1] != ':' : + RegionData = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData) + if not os.path.exists(RegionData): + EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData) + + BinFile = open (RegionData, 'r+b') + FvBuffer.write(BinFile.read()) + if FvBuffer.len > Size : + EdkLogger.error("GenFds", GENFDS_ERROR, + "Size of File (%s) large than Region Size " % RegionData) + + # + # If File contents less than region size, append "0xff" after it + # + if FvBuffer.len < Size: + for index in range(0, (Size-FvBuffer.len)): + if (ErasePolarity == '1'): + FvBuffer.write(pack('B', int('0xFF', 16))) + else: + FvBuffer.write(pack('B', int('0x00', 16))) + Buffer.write(FvBuffer.getvalue()) + FvBuffer.close() + + if self.RegionType == 'DATA' : + GenFdsGlobalVariable.InfLogger(' Region Name = DATA') + DataSize = 0 + for RegionData in self.RegionDataList: + Data = RegionData.split(',') + DataSize = DataSize + len(Data) + if DataSize > Size: + EdkLogger.error("GenFds", GENFDS_ERROR, "Size of DATA is larger than Region Size ") + else: + for item in Data : + Buffer.write(pack('B', int(item, 16))) + if DataSize < Size: + if (ErasePolarity == '1'): + PadData = 0xFF + else: + PadData = 0 + for i in range(Size - DataSize): + Buffer.write(pack('B', PadData)) + + if self.RegionType == None: + GenFdsGlobalVariable.InfLogger(' Region Name = None') + if (ErasePolarity == '1') : + PadData = 0xFF + else : + PadData = 0 + for i in range(0, Size): + Buffer.write(pack('B', PadData)) + + def GetFvAlignValue(self, Str): + AlignValue = 1 + Granu = 1 + Str = Str.strip().upper() + if Str.endswith('K'): + Granu = 1024 + Str = Str[:-1] + elif Str.endswith('M'): + Granu = 1024*1024 + Str = Str[:-1] + elif Str.endswith('G'): + Granu = 1024*1024*1024 + Str = Str[:-1] + else: + pass + + AlignValue = int(Str)*Granu + return AlignValue + ## BlockSizeOfRegion() + # + # @param BlockSizeList List of block information + # @retval int Block size of region + # + def BlockSizeOfRegion(self, BlockSizeList): + Offset = 0x00 + BlockSize = 0 + for item in BlockSizeList: + Offset = Offset + item[0] * item[1] + GenFdsGlobalVariable.VerboseLogger ("Offset = 0x%X" %Offset) + GenFdsGlobalVariable.VerboseLogger ("self.Offset 0x%X" %self.Offset) + + if self.Offset < Offset : + if Offset - self.Offset < self.Size: + EdkLogger.error("GenFds", GENFDS_ERROR, + "Region at Offset 0x%X can NOT fit into Block array with BlockSize %X" \ + % (self.Offset, item[0])) + BlockSize = item[0] + GenFdsGlobalVariable.VerboseLogger ("BlockSize = %X" %BlockSize) + return BlockSize + return BlockSize + + ## BlockNumOfRegion() + # + # @param BlockSize block size of region + # @retval int Block number of region + # + def BlockNumOfRegion (self, BlockSize): + if BlockSize == 0 : + EdkLogger.error("GenFds", GENFDS_ERROR, "Region: %s is not in the FD address scope!" % self.Offset) + BlockNum = self.Size / BlockSize + GenFdsGlobalVariable.VerboseLogger ("BlockNum = 0x%X" %BlockNum) + return BlockNum + diff --git a/BaseTools/Source/Python/GenFds/Rule.py b/BaseTools/Source/Python/GenFds/Rule.py new file mode 100644 index 0000000000..40a5f88bab --- /dev/null +++ b/BaseTools/Source/Python/GenFds/Rule.py @@ -0,0 +1,29 @@ +## @file +# Rule object for generating FFS +# +# Copyright (c) 2007, 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 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 +# +from CommonDataClass.FdfClass import RuleClassObject + +## Rule base class +# +# +class Rule(RuleClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + RuleClassObject.__init__(self) diff --git a/BaseTools/Source/Python/GenFds/RuleComplexFile.py b/BaseTools/Source/Python/GenFds/RuleComplexFile.py new file mode 100644 index 0000000000..63e65c5970 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/RuleComplexFile.py @@ -0,0 +1,30 @@ +## @file +# Complex Rule object for generating FFS +# +# Copyright (c) 2007, 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 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 Rule +from CommonDataClass.FdfClass import RuleComplexFileClassObject + +## complex rule +# +# +class RuleComplexFile(RuleComplexFileClassObject) : + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + RuleComplexFileClassObject.__init__(self) diff --git a/BaseTools/Source/Python/GenFds/RuleSimpleFile.py b/BaseTools/Source/Python/GenFds/RuleSimpleFile.py new file mode 100644 index 0000000000..c6fdbd88dc --- /dev/null +++ b/BaseTools/Source/Python/GenFds/RuleSimpleFile.py @@ -0,0 +1,30 @@ +## @file +# Simple Rule object for generating FFS +# +# Copyright (c) 2007, 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 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 Rule +from CommonDataClass.FdfClass import RuleSimpleFileClassObject + +## simple rule +# +# +class RuleSimpleFile (RuleSimpleFileClassObject) : + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + RuleSimpleFileClassObject.__init__(self) diff --git a/BaseTools/Source/Python/GenFds/Section.py b/BaseTools/Source/Python/GenFds/Section.py new file mode 100644 index 0000000000..ffca3a11fe --- /dev/null +++ b/BaseTools/Source/Python/GenFds/Section.py @@ -0,0 +1,153 @@ +## @file +# section base class +# +# Copyright (c) 2007, 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 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 +# +from CommonDataClass.FdfClass import SectionClassObject +from GenFdsGlobalVariable import GenFdsGlobalVariable +import os, glob +from Common import EdkLogger +from Common.BuildToolError import * + +## section base class +# +# +class Section (SectionClassObject): + SectionType = { + 'RAW' : 'EFI_SECTION_RAW', + 'FREEFORM' : 'EFI_SECTION_FREEFORM_SUBTYPE_GUID', + 'PE32' : 'EFI_SECTION_PE32', + 'PIC' : 'EFI_SECTION_PIC', + 'TE' : 'EFI_SECTION_TE', + 'FV_IMAGE' : 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', + 'DXE_DEPEX' : 'EFI_SECTION_DXE_DEPEX', + 'PEI_DEPEX' : 'EFI_SECTION_PEI_DEPEX', + 'GUIDED' : 'EFI_SECTION_GUID_DEFINED', + 'COMPRESS' : 'EFI_SECTION_COMPRESSION', + 'UI' : 'EFI_SECTION_USER_INTERFACE', + 'SMM_DEPEX' : 'EFI_SECTION_SMM_DEPEX' + } + + BinFileType = { + 'GUID' : '.guid', + 'ACPI' : '.acpi', + 'ASL' : '.asl' , + 'UEFI_APP' : '.app', + 'LIB' : '.lib', + 'PE32' : '.pe32', + 'PIC' : '.pic', + 'PEI_DEPEX' : '.depex', + 'SEC_PEI_DEPEX' : '.depex', + 'TE' : '.te', + 'UNI_VER' : '.ver', + 'VER' : '.ver', + 'UNI_UI' : '.ui', + 'UI' : '.ui', + 'BIN' : '.bin', + 'RAW' : '.raw', + 'COMPAT16' : '.comp16', + 'FV' : '.fv' + } + + SectFileType = { + 'SEC_GUID' : '.sec' , + 'SEC_PE32' : '.sec' , + 'SEC_PIC' : '.sec', + 'SEC_TE' : '.sec', + 'SEC_VER' : '.sec', + 'SEC_UI' : '.sec', + 'SEC_COMPAT16' : '.sec', + 'SEC_BIN' : '.sec' + } + + ToolGuid = { + '0xa31280ad-0x481e-0x41b6-0x95e8-0x127f-0x4c984779' : 'TianoCompress', + '0xee4e5898-0x3914-0x4259-0x9d6e-0xdc7b-0xd79403cf' : 'LzmaCompress' + } + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + SectionClassObject.__init__(self) + + ## GenSection() method + # + # virtual function + # + # @param self The object pointer + # @param OutputPath Where to place output file + # @param ModuleName Which module this section belongs to + # @param SecNum Index of section + # @param KeyStringList Filter for inputs of section generation + # @param FfsInf FfsInfStatement object that contains this section data + # @param Dict dictionary contains macro and its value + # + def GenSection(self, OutputPath, GuidName, SecNum, keyStringList, FfsInf = None, Dict = {}): + pass + + ## GetFileList() method + # + # Generate compressed section + # + # @param self The object pointer + # @param FfsInf FfsInfStatement object that contains file list + # @param FileType File type to get + # @param FileExtension File extension to get + # @param Dict dictionary contains macro and its value + # @retval tuple (File list, boolean) + # + def GetFileList(FfsInf, FileType, FileExtension, Dict = {}): + if FileType in Section.SectFileType.keys() : + IsSect = True + else : + IsSect = False + + if FileExtension != None: + Suffix = FileExtension + elif IsSect : + Suffix = Section.SectionType.get(FileType) + else: + Suffix = Section.BinFileType.get(FileType) + if FfsInf == None: + EdkLogger.error("GenFds", GENFDS_ERROR, 'Inf File does not exist!') + + FileList = [] + if FileType != None: + for File in FfsInf.BinFileList: + if File.Arch == "COMMON" or FfsInf.CurrentArch == File.Arch: + if File.Type == FileType: + if '*' in FfsInf.TargetOverrideList or File.Target == '*' or File.Target in FfsInf.TargetOverrideList or FfsInf.TargetOverrideList == []: + FileList.append(File.Path) + else: + GenFdsGlobalVariable.InfLogger ("\nBuild Target \'%s\' of File %s is not in the Scope of %s specified by INF %s in FDF" %(File.Target, File.File, FfsInf.TargetOverrideList, FfsInf.InfFileName)) + else: + GenFdsGlobalVariable.VerboseLogger ("\nFile Type \'%s\' of File %s in %s is not same with file type \'%s\' from Rule in FDF" %(File.Type, File.File, FfsInf.InfFileName, FileType)) + 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): +# FileList.extend(glob.glob(os.path.join(FfsInf.EfiOutputPath, "*" + Suffix))) + # 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) + + return FileList, IsSect + GetFileList = staticmethod(GetFileList) diff --git a/BaseTools/Source/Python/GenFds/UiSection.py b/BaseTools/Source/Python/GenFds/UiSection.py new file mode 100644 index 0000000000..e660055f9a --- /dev/null +++ b/BaseTools/Source/Python/GenFds/UiSection.py @@ -0,0 +1,77 @@ +## @file +# process UI section generation +# +# Copyright (c) 2007, 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 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 Section +from Ffs import Ffs +import subprocess +import os +from GenFdsGlobalVariable import GenFdsGlobalVariable +from CommonDataClass.FdfClass import UiSectionClassObject + +## generate UI section +# +# +class UiSection (UiSectionClassObject): + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + UiSectionClassObject.__init__(self) + + ## GenSection() method + # + # Generate UI section + # + # @param self The object pointer + # @param OutputPath Where to place output file + # @param ModuleName Which module this section belongs to + # @param SecNum Index of section + # @param KeyStringList Filter for inputs of section generation + # @param FfsInf FfsInfStatement object that contains this section data + # @param Dict dictionary contains macro and its value + # @retval tuple (Generated file name, section alignment) + # + def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}): + # + # Prepare the parameter of GenSection + # + if FfsInf != None: + self.Alignment = FfsInf.__ExtendMacro__(self.Alignment) + self.StringData = FfsInf.__ExtendMacro__(self.StringData) + self.FileName = FfsInf.__ExtendMacro__(self.FileName) + + OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + SecNum + Ffs.SectionSuffix.get('UI')) + + if self.StringData != None : + NameString = self.StringData + elif self.FileName != None: + FileNameStr = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName) + FileNameStr = GenFdsGlobalVariable.MacroExtend(FileNameStr, Dict) + FileObj = open(FileNameStr, 'r') + NameString = FileObj.read() + NameString = '\"' + NameString + "\"" + FileObj.close() + else: + NameString = '' + + GenFdsGlobalVariable.GenerateSection(OutputFile, None, 'EFI_SECTION_USER_INTERFACE', Ui=NameString) + + OutputFileList = [] + OutputFileList.append(OutputFile) + return OutputFileList, self.Alignment diff --git a/BaseTools/Source/Python/GenFds/VerSection.py b/BaseTools/Source/Python/GenFds/VerSection.py new file mode 100644 index 0000000000..e27d0a20f9 --- /dev/null +++ b/BaseTools/Source/Python/GenFds/VerSection.py @@ -0,0 +1,82 @@ +## @file +# process Version section generation +# +# Copyright (c) 2007, 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 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 +# +from Ffs import Ffs +import Section +import os +import subprocess +from GenFdsGlobalVariable import GenFdsGlobalVariable +from CommonDataClass.FdfClass import VerSectionClassObject + +## generate version section +# +# +class VerSection (VerSectionClassObject): + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + VerSectionClassObject.__init__(self) + + ## GenSection() method + # + # Generate version section + # + # @param self The object pointer + # @param OutputPath Where to place output file + # @param ModuleName Which module this section belongs to + # @param SecNum Index of section + # @param KeyStringList Filter for inputs of section generation + # @param FfsInf FfsInfStatement object that contains this section data + # @param Dict dictionary contains macro and its value + # @retval tuple (Generated file name, section alignment) + # + def GenSection(self,OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}): + # + # Prepare the parameter of GenSection + # + if FfsInf != None: + self.Alignment = FfsInf.__ExtendMacro__(self.Alignment) + self.BuildNum = FfsInf.__ExtendMacro__(self.BuildNum) + self.StringData = FfsInf.__ExtendMacro__(self.StringData) + self.FileName = FfsInf.__ExtendMacro__(self.FileName) + + OutputFile = os.path.join(OutputPath, + ModuleName + 'SEC' + SecNum + Ffs.SectionSuffix.get('VERSION')) + OutputFile = os.path.normpath(OutputFile) + + # Get String Data + StringData = '' + if self.StringData != None: + StringData = self.StringData + elif self.FileName != None: + FileNameStr = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName) + FileNameStr = GenFdsGlobalVariable.MacroExtend(FileNameStr, Dict) + FileObj = open(FileNameStr, 'r') + StringData = FileObj.read() + StringData = '"' + StringData + '"' + FileObj.close() + else: + StringData = '' + + GenFdsGlobalVariable.GenerateSection(OutputFile, None, 'EFI_SECTION_VERSION', + Ui=StringData, Ver=self.BuildNum) + OutputFileList = [] + OutputFileList.append(OutputFile) + return OutputFileList, self.Alignment diff --git a/BaseTools/Source/Python/GenFds/Vtf.py b/BaseTools/Source/Python/GenFds/Vtf.py new file mode 100644 index 0000000000..eebc7b1dab --- /dev/null +++ b/BaseTools/Source/Python/GenFds/Vtf.py @@ -0,0 +1,188 @@ +## @file +# process VTF generation +# +# Copyright (c) 2007, 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 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 +# +from GenFdsGlobalVariable import GenFdsGlobalVariable +import os +from CommonDataClass.FdfClass import VtfClassObject +T_CHAR_LF = '\n' + +## generate VTF +# +# +class Vtf (VtfClassObject): + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + VtfClassObject.__init__(self) + + ## GenVtf() method + # + # Generate VTF + # + # @param self The object pointer + # @param FdAddressDict dictionary contains FV name and its base address + # @retval Dict FV and corresponding VTF file name + # + def GenVtf(self, FdAddressDict) : + self.GenBsfInf() + OutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.UiName + '.Vtf') + BaseAddArg = self.GetBaseAddressArg(FdAddressDict) + OutputArg, VtfRawDict = self.GenOutputArg() + + Cmd = ( + 'GenVtf', + ) + OutputArg + ( + '-f', self.BsfInfName, + ) + BaseAddArg + + GenFdsGlobalVariable.CallExternalTool(Cmd, "GenFv -Vtf Failed!") + GenFdsGlobalVariable.SharpCounter = 0 + + return VtfRawDict + + ## GenBsfInf() method + # + # Generate inf used to generate VTF + # + # @param self The object pointer + # + def GenBsfInf (self): + FvList = self.GetFvList() + self.BsfInfName = os.path.join(GenFdsGlobalVariable.FvDir, self.UiName + '.inf') + BsfInf = open (self.BsfInfName, 'w+') + BsfInf.writelines ("[COMPONENTS]" + T_CHAR_LF) + + for ComponentObj in self.ComponentStatementList : + BsfInf.writelines ("COMP_NAME" + \ + " = " + \ + ComponentObj.CompName + \ + T_CHAR_LF ) + if ComponentObj.CompLoc.upper() == 'NONE': + BsfInf.writelines ("COMP_LOC" + \ + " = " + \ + 'N' + \ + T_CHAR_LF ) + + elif ComponentObj.FilePos != None: + BsfInf.writelines ("COMP_LOC" + \ + " = " + \ + ComponentObj.FilePos + \ + T_CHAR_LF ) + else: + Index = FvList.index(ComponentObj.CompLoc.upper()) + if Index == 0: + BsfInf.writelines ("COMP_LOC" + \ + " = " + \ + 'F' + \ + T_CHAR_LF ) + elif Index == 1: + BsfInf.writelines ("COMP_LOC" + \ + " = " + \ + 'S' + \ + T_CHAR_LF ) + + BsfInf.writelines ("COMP_TYPE" + \ + " = " + \ + ComponentObj.CompType + \ + T_CHAR_LF ) + BsfInf.writelines ("COMP_VER" + \ + " = " + \ + ComponentObj.CompVer + \ + T_CHAR_LF ) + BsfInf.writelines ("COMP_CS" + \ + " = " + \ + ComponentObj.CompCs + \ + T_CHAR_LF ) + + BinPath = ComponentObj.CompBin + if BinPath != '-': + BinPath = GenFdsGlobalVariable.MacroExtend(GenFdsGlobalVariable.ReplaceWorkspaceMacro(BinPath)) + BsfInf.writelines ("COMP_BIN" + \ + " = " + \ + BinPath + \ + T_CHAR_LF ) + + SymPath = ComponentObj.CompSym + if SymPath != '-': + SymPath = GenFdsGlobalVariable.MacroExtend(GenFdsGlobalVariable.ReplaceWorkspaceMacro(SymPath)) + BsfInf.writelines ("COMP_SYM" + \ + " = " + \ + SymPath + \ + T_CHAR_LF ) + BsfInf.writelines ("COMP_SIZE" + \ + " = " + \ + ComponentObj.CompSize + \ + T_CHAR_LF ) + BsfInf.writelines (T_CHAR_LF ) + + BsfInf.close() + + ## GenFvList() method + # + # Get FV list referenced by VTF components + # + # @param self The object pointer + # + def GetFvList(self): + FvList = [] + for component in self.ComponentStatementList : + if component.CompLoc.upper() != 'NONE' and not (component.CompLoc.upper() in FvList): + FvList.append(component.CompLoc.upper()) + + return FvList + + ## GetBaseAddressArg() method + # + # Get base address arguments for GenVtf + # + # @param self The object pointer + # + def GetBaseAddressArg(self, FdAddressDict): + FvList = self.GetFvList() + CmdStr = tuple() + for i in FvList: + (BaseAddress, Size) = FdAddressDict.get(i) + CmdStr += ( + '-r', '0x%x' % BaseAddress, + '-s', '0x%x' %Size, + ) + return CmdStr + + ## GenOutputArg() method + # + # Get output arguments for GenVtf + # + # @param self The object pointer + # + def GenOutputArg(self): + FvVtfDict = {} + OutputFileName = '' + FvList = self.GetFvList() + Index = 0 + Arg = tuple() + for FvObj in FvList: + Index = Index + 1 + OutputFileName = 'Vtf%d.raw' % Index + OutputFileName = os.path.join(GenFdsGlobalVariable.FvDir, OutputFileName) + Arg += ('-o', OutputFileName) + FvVtfDict[FvObj.upper()] = OutputFileName + + return Arg, FvVtfDict + diff --git a/BaseTools/Source/Python/GenFds/__init__.py b/BaseTools/Source/Python/GenFds/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/BaseTools/Source/Python/Makefile b/BaseTools/Source/Python/Makefile new file mode 100644 index 0000000000..a4e76592ab --- /dev/null +++ b/BaseTools/Source/Python/Makefile @@ -0,0 +1,89 @@ + +!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 + +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 + +COMMON_PYTHON=$(BASE_TOOLS_PATH)\Source\Python\Common\BuildToolError.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\Database.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\DataType.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\DecClassObject.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\DecClassObjectLight.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\Dictionary.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\DscClassObject.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\EdkIIWorkspace.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\EdkIIWorkspaceBuild.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\EdkLogger.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\FdfClassObject.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\FdfParserLite.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\GlobalData.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\Identification.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\InfClassObject.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\InfClassObjectLight.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\MigrationUtilities.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\Misc.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\Parsing.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\String.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\TargetTxtClassObject.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\ToolDefClassObject.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\XmlParser.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\XmlRoutines.py \ + $(BASE_TOOLS_PATH)\Source\Python\Common\__init__.py \ + $(BASE_TOOLS_PATH)\Source\Python\Workspace\BuildClassObject.py \ + $(BASE_TOOLS_PATH)\Source\Python\Workspace\MetaDataTable.py \ + $(BASE_TOOLS_PATH)\Source\Python\Workspace\MetaFileParser.py \ + $(BASE_TOOLS_PATH)\Source\Python\Workspace\MetaFileTable.py \ + $(BASE_TOOLS_PATH)\Source\Python\Workspace\WorkspaceDatabase.py \ + $(BASE_TOOLS_PATH)\Source\Python\Workspace\__init__.py \ + $(BASE_TOOLS_PATH)\Source\Python\Autogen\AutoGen.py \ + $(BASE_TOOLS_PATH)\Source\Python\Autogen\BuildEngine.py \ + $(BASE_TOOLS_PATH)\Source\Python\Autogen\GenC.py \ + $(BASE_TOOLS_PATH)\Source\Python\Autogen\GenDepex.py \ + $(BASE_TOOLS_PATH)\Source\Python\Autogen\GenMake.py \ + $(BASE_TOOLS_PATH)\Source\Python\Autogen\StrGather.py \ + $(BASE_TOOLS_PATH)\Source\Python\Autogen\UniClassObject.py \ + $(BASE_TOOLS_PATH)\Source\Python\Autogen\__init__.py + + +all: SetPythonPath $(APPLICATIONS) + +SetPythonPath: + set PYTHONPATH=$(BASE_TOOLS_PATH)\Source\Python + +$(BIN_DIR)\build.exe: $(BASE_TOOLS_PATH)\Source\Python\build\build.py $(COMMON_PYTHON) + @pushd . & @cd build & @$(FREEZE) --include-modules=$(MODULES) --install-dir=$(BIN_DIR) build.py & @popd + +$(BIN_DIR)\GenFds.exe: $(BASE_TOOLS_PATH)\Source\Python\GenFds\GenFds.py $(COMMON_PYTHON) + @pushd . & @cd GenFds & @$(FREEZE) --include-modules=$(MODULES) --install-dir=$(BIN_DIR) GenFds.py & @popd + +$(BIN_DIR)\Trim.exe: $(BASE_TOOLS_PATH)\Source\Python\Trim\Trim.py $(COMMON_PYTHON) + @pushd . & @cd Trim & @$(FREEZE) --include-modules=$(MODULES) --install-dir=$(BIN_DIR) Trim.py & @popd + +$(BIN_DIR)\MigrationMsa2Inf.exe: $(BASE_TOOLS_PATH)\Source\Python\MigrationMsa2Inf\MigrationMsa2Inf.py + @pushd . & @cd MigrationMsa2Inf & @$(FREEZE) --include-modules=$(MODULES) --install-dir=$(BIN_DIR) MigrationMsa2Inf.py & @popd + +$(BIN_DIR)\Fpd2Dsc.exe: $(BASE_TOOLS_PATH)\Source\Python\Fpd2Dsc\Fpd2Dsc.py $(COMMON_PYTHON) + @pushd . & @cd Fpd2Dsc & @$(FREEZE) --include-modules=$(MODULES) --install-dir=$(BIN_DIR) Fpd2Dsc.py & @popd + +$(BIN_DIR)\spd2dec.exe: $(BASE_TOOLS_PATH)\Source\Python\spd2dec\Spd2Dec.py $(COMMON_PYTHON) + @pushd . & @cd Spd2Dec & @$(FREEZE) --include-modules=$(MODULES) --install-dir=$(BIN_DIR) Spd2Dec.py & @popd + +$(BIN_DIR)\GenDepex.exe: $(BASE_TOOLS_PATH)\Source\Python\AutoGen\GenDepex.py $(COMMON_PYTHON) + @pushd . & @cd AutoGen & @$(FREEZE) --include-modules=$(MODULES) --install-dir=$(BIN_DIR) GenDepex.py & @popd + +$(BIN_DIR)\TargetTool.exe: $(BASE_TOOLS_PATH)\Source\Python\TargetTool\TargetTool.py $(COMMON_PYTHON) + @pushd . & @cd TargetTool & @$(FREEZE) --include-modules=$(MODULES) --install-dir=$(BIN_DIR) TargetTool.py & @popd + +clean: +cleanall: + @del /f /q $(BIN_DIR)\*.pyd $(BIN_DIR)\*.dll + @for %%i in ($(APPLICATIONS)) do @del /f /q %%i + diff --git a/BaseTools/Source/Python/MigrationMsa2Inf/AutoGenExterns.py b/BaseTools/Source/Python/MigrationMsa2Inf/AutoGenExterns.py new file mode 100644 index 0000000000..16f7a6bb2e --- /dev/null +++ b/BaseTools/Source/Python/MigrationMsa2Inf/AutoGenExterns.py @@ -0,0 +1,369 @@ +#!/usr/bin/env python +# +# +# Copyright (c) 2007, 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 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 re, os, glob +from Common.XmlRoutines import * + +#"ModuleType"=>(PackageGuid, headerFileName) List +HeaderFiles = {} +GuidList = [] +GuidMap = {} +HeaderFileContents = {} +gTest = {} +GuidMacro2CName = {} +GuidAliasList = [] + +def collectIncludeFolder(pkgDirName, guidType, pkgName): + includeFolder = os.path.join(pkgDirName, "Include", guidType) + if os.path.exists(includeFolder) and os.path.isdir(includeFolder): + for headerFileName in os.listdir(includeFolder): + if headerFileName[-2:] == ".h": + headerFile = open(os.path.join(includeFolder, headerFileName)) + HeaderFileContents[(guidType, headerFileName, pkgName)] = headerFile.read() + headerFile.close() + +GuidMacroReg = re.compile(r"\b(?!EFI_GUID\b)[A-Z0-9_]+_GUID\b") +GuidCNameReg = re.compile(r"\bg\w+Guid\b") +GuidAliasReg = re.compile(r"#define\s+([A-Z0-9_]+_GUID)\s+([A-Z0-9_]+_GUID)\b") + +def collectPackageInfo(spdFileName): + pkgDirName = os.path.dirname(spdFileName) + + spd = XmlParseFile(spdFileName) + + pkgName = XmlElement(spd, "/PackageSurfaceArea/SpdHeader/PackageName") + pkgGuid = XmlElement(spd, "/PackageSurfaceArea/SpdHeader/GuidValue") + + + for IncludePkgHeader in XmlList(spd, "/PackageSurfaceArea/PackageHeaders/IncludePkgHeader"): + moduleType = XmlAttribute(IncludePkgHeader, "ModuleType") + headerFilePath = XmlElementData(IncludePkgHeader) + headerFilePath = re.sub("Include/", "", headerFilePath, 1) + + headerTuple = HeaderFiles.get(moduleType, []) + headerTuple.append((pkgGuid, headerFilePath)) + HeaderFiles[moduleType] = headerTuple + + guidTypes = ["Guid", "Protocol", "Ppi"] + + for guidType in guidTypes: + for guidEntry in XmlList(spd, "/PackageSurfaceArea/" + guidType + "Declarations/Entry"): + guidCName = XmlElement(guidEntry, "Entry/C_Name") + GuidList.append(guidCName) + + collectIncludeFolder(pkgDirName, guidType, pkgName) + + for DecFile in glob.glob(os.path.join(pkgDirName, "*.dec")): + fileContents = open(DecFile).read() + for GuidCNameMatch in GuidCNameReg.finditer(fileContents): + GuidCName = GuidCNameMatch.group(0) + if GuidCName not in GuidList: + GuidList.append(GuidCName) + +def AddGuidMacro2GuidCName(GuidMacros, GuidCNames): + for GuidMacro in GuidMacros: + GuessGuidCName = "g" + GuidMacro.lower().title().replace("_", "") + if GuessGuidCName in GuidCNames: + GuidMacro2CName[GuidMacro] = GuessGuidCName + elif len(GuidCNames) == 1: + GuidMacro2CName[GuidMacro] = GuidCNames[0] + else: + for GuidCName in GuidCNames: + if GuidCName.lower() == GuessGuidCName.lower(): + GuidMacro2CName[GuidMacro] = GuidCName + break + else: + pass + #print "No matching GuidMacro %s" % GuidMacro + + +def TranslateGuid(GuidMacroMatch): + GuidMacro = GuidMacroMatch.group(0) + return GuidMacro2CName.get(GuidMacro, GuidMacro) + +DepexReg = re.compile(r"DEPENDENCY_START(.*?)DEPENDENCY_END", re.DOTALL) + +def TranslateDpxSection(fileContents): + DepexMatch = DepexReg.search(fileContents) + if not DepexMatch: + return "", [] + + fileContents = DepexMatch.group(1) + fileContents = re.sub(r"\s+", " ", fileContents).strip() + fileContents = GuidMacroReg.sub(TranslateGuid, fileContents) + return fileContents, GuidMacroReg.findall(fileContents) + +def InitializeAutoGen(workspace, db): + + + for spdFile in XmlList(db, "/FrameworkDatabase/PackageList/Filename"): + spdFileName = XmlElementData(spdFile) + collectPackageInfo(os.path.join(workspace, spdFileName)) + + + BlockCommentReg = re.compile(r"/\*.*?\*/", re.DOTALL) + LineCommentReg = re.compile(r"//.*") + GuidReg = re.compile(r"\b(" + '|'.join(GuidList) + r")\b") + + for headerFile in HeaderFileContents: + Contents = HeaderFileContents[headerFile] + Contents = BlockCommentReg.sub("", Contents) + Contents = LineCommentReg.sub("", Contents) + + FoundGuids = GuidReg.findall(Contents) + for FoundGuid in FoundGuids: + GuidMap[FoundGuid] = "%s/%s" % (headerFile[0], headerFile[1]) + #print "%-40s %s/%s" % (FoundGuid, headerFile[0], headerFile[1]) + + GuidMacros = GuidMacroReg.findall(Contents) + GuidCNames = GuidCNameReg.findall(Contents) + + for GuidAliasMatch in GuidAliasReg.finditer(Contents): + Name1, Name2 = GuidAliasMatch.group(1), GuidAliasMatch.group(2) + GuidAliasList.append((Name1, Name2)) + + AddGuidMacro2GuidCName(GuidMacros, GuidCNames) + +def AddSystemIncludeStatement(moduleType, PackageList): + IncludeStatement = "\n" + + headerList = HeaderFiles.get(moduleType, []) + + for pkgGuid in PackageList: + + for pkgTuple in headerList: + if pkgTuple[0] == pkgGuid: + IncludeStatement += "#include <%s>\n" % pkgTuple[1] + + return IncludeStatement + + +def AddLibraryClassStatement(LibraryClassList): + IncludeStatement = "\n" + for LibraryClass in LibraryClassList: + IncludeStatement += "#include \n" % LibraryClass + + return IncludeStatement + +def AddGuidStatement(GuidList): + IncludeStatement = "\n" + GuidIncludeSet = {} + for Guid in GuidList: + if Guid in GuidMap: + GuidIncludeSet[GuidMap[Guid]] = 1 + else: + print "GUID CName: %s cannot be found in any public header file" % Guid + + for GuidInclude in GuidIncludeSet: + IncludeStatement += "#include <%s>\n" % GuidInclude + + return IncludeStatement + +DriverBindingMap = { + "gEfiDriverBindingProtocolGuid" : "EFI_DRIVER_BINDING_PROTOCOL", + "gEfiComponentNameProtocolGuid" : "EFI_COMPONENT_NAME_PROTOCOL", + "gEfiDriverConfigurationProtocolGuid" : "EFI_DRIVER_CONFIGURATION_PROTOCOL", + "gEfiDriverDiagnosticProtocolGuid" : "EFI_DRIVER_CONFIGURATION_PROTOCOL" + } + +def AddDriverBindingProtocolStatement(AutoGenDriverModel): + InstallStatement = "\n" + DBindingHandle = "ImageHandle" + GlobalDeclaration = "\n" + + + for DriverModelItem in AutoGenDriverModel: + + if DriverModelItem[1] == "NULL" and DriverModelItem[2] == "NULL" and DriverModelItem[3] == "NULL": + InstallStatement += " Status = EfiLibInstallDriverBinding (\n" + InstallStatement += " ImageHandle,\n" + InstallStatement += " SystemTable,\n" + InstallStatement += " %s,\n" % DriverModelItem[0] + InstallStatement += " %s\n" % DBindingHandle + InstallStatement += " );\n" + else: + InstallStatement += " Status = EfiLibInstallAllDriverProtocols (\n" + InstallStatement += " ImageHandle,\n" + InstallStatement += " SystemTable,\n" + InstallStatement += " %s,\n" % DriverModelItem[0] + InstallStatement += " %s,\n" % DBindingHandle + InstallStatement += " %s,\n" % DriverModelItem[1] + InstallStatement += " %s,\n" % DriverModelItem[2] + InstallStatement += " %s\n" % DriverModelItem[3] + InstallStatement += " );\n" + + InstallStatement += " ASSERT_EFI_ERROR (Status);\n\n" + + GlobalDeclaration += "extern EFI_DRIVER_BINDING_PROTOCOL %s;\n" % DriverModelItem[0][1:] + if (DriverModelItem[1] != "NULL"): + GlobalDeclaration += "extern EFI_COMPONENT_NAME_PROTOCOL %s;\n" % DriverModelItem[1][1:] + if (DriverModelItem[2] != "NULL"): + GlobalDeclaration += "extern EFI_DRIVER_CONFIGURATION_PROTOCOL %s;\n" % DriverModelItem[2][1:] + if (DriverModelItem[3] != "NULL"): + GlobalDeclaration += "extern EFI_DRIVER_CONFIGURATION_PROTOCOL %s;\n" % DriverModelItem[3][1:] + + DBindingHandle = "NULL" + + return (InstallStatement, "", "", GlobalDeclaration) + +EventDeclarationTemplate = """ +// +// Declaration for callback Event. +// +VOID +EFIAPI +%s ( + IN EFI_EVENT Event, + IN VOID *Context + ); +""" + +def AddBootServiceEventStatement(EventList): + FinalEvent = "" + if len(EventList) > 1: + + print "Current prototype does not support multi boot service event" + else: + FinalEvent = EventList[0] + + CreateStatement = "\n" + CreateStatement += " Status = gBS->CreateEvent (\n" + CreateStatement += " EVT_SIGNAL_EXIT_BOOT_SERVICES,\n" + CreateStatement += " EFI_TPL_NOTIFY,\n" + CreateStatement += " " + FinalEvent + ",\n" + CreateStatement += " NULL,\n" + CreateStatement += " &mExitBootServicesEvent\n" + CreateStatement += " );\n" + CreateStatement += " ASSERT_EFI_ERROR (Status);\n" + + GlobalDefinition = "\n" + GlobalDefinition += "STATIC EFI_EVENT mExitBootServicesEvent = NULL;\n" + + GlobalDeclaration = EventDeclarationTemplate % FinalEvent + + DestroyStatement = "\n" + DestroyStatement += " Status = gBS->CloseEvent (mExitBootServicesEvent);\n" + DestroyStatement += " ASSERT_EFI_ERROR (Status);\n" + return (CreateStatement, "", GlobalDefinition, GlobalDeclaration) + +def AddVirtualAddressEventStatement(EventList): + FinalEvent = "" + if len(EventList) > 1: + print "Current prototype does not support multi virtual address change event" + else: + FinalEvent = EventList[0] + + CreateStatement = "\n" + + CreateStatement += " Status = gBS->CreateEvent (\n" + CreateStatement += " EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,\n" + CreateStatement += " TPL_NOTIFY,\n" + CreateStatement += " " + FinalEvent + ",\n" + CreateStatement += " NULL,\n" + CreateStatement += " &mVirtualAddressChangedEvent\n" + CreateStatement += " );\n" + CreateStatement += " ASSERT_EFI_ERROR (Status);\n" + + GlobalDefinition = "\n" + GlobalDefinition += "STATIC EFI_EVENT mVirtualAddressChangedEvent = NULL;\n" + + GlobalDeclaration = EventDeclarationTemplate % FinalEvent + + DestroyStatement = "\n" + DestroyStatement += " Status = gBS->CloseEvent (mVirtualAddressChangedEvent);\n" + DestroyStatement += " ASSERT_EFI_ERROR (Status);\n" + + return (CreateStatement, "", GlobalDefinition, GlobalDeclaration) + + +EntryPointDeclarationTemplate = """ +// +// Declaration for original Entry Point. +// +EFI_STATUS +EFIAPI +%s ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); +""" + +EntryPointHeader = r""" +/** + The user Entry Point for module %s. The user code starts with this function. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry point. + +**/ +""" +def AddNewEntryPointContentsStatement (moduleName, EntryPoint, InstallStatement = ""): + if EntryPoint != "Initialize%s" % moduleName: + NewEntryPoint = "Initialize%s" % moduleName + else: + NewEntryPoint = "NewInitialize%s" % moduleName + + EntryPointContents = EntryPointHeader % moduleName + EntryPointContents += "EFI_STATUS\n" + EntryPointContents += "EFIAPI\n" + EntryPointContents += NewEntryPoint + "(\n" + EntryPointContents += " IN EFI_HANDLE ImageHandle,\n" + EntryPointContents += " IN EFI_SYSTEM_TABLE *SystemTable\n" + EntryPointContents += " )\n" + EntryPointContents += "{\n" + EntryPointContents += " EFI_STATUS Status;\n" + EntryPointContents += InstallStatement + "\n" + GlobalDeclaration = "" + + if EntryPoint != "": + EntryPointContents += " //\n // Call the original Entry Point\n //\n" + EntryPointContents += " Status = %s (ImageHandle, SystemTable);\n\n" % EntryPoint + GlobalDeclaration += EntryPointDeclarationTemplate % EntryPoint + + EntryPointContents += " return Status;\n" + EntryPointContents += "}\n" + + return (NewEntryPoint, EntryPointContents, GlobalDeclaration) + +reFileHeader = re.compile(r"^\s*/\*.*?\*/\s*", re.DOTALL) +reNext = re.compile(r"#ifndef\s*(\w+)\s*#define\s*\1\s*") + +def AddCommonInclusionStatement(fileContents, includeStatement): + if includeStatement in fileContents: + return fileContents + + insertPos = 0 + matchFileHeader = reFileHeader.search(fileContents) + if matchFileHeader: + insertPos = matchFileHeader.end() + + matchFileHeader = reNext.search(fileContents, insertPos) + if matchFileHeader: + insertPos = matchFileHeader.end() + + includeStatement = "\n%s\n\n" % includeStatement + fileContents = fileContents[0:insertPos] + includeStatement + fileContents[insertPos:] + return fileContents + +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +if __name__ == '__main__': + + pass + diff --git a/BaseTools/Source/Python/MigrationMsa2Inf/MigrationMsa2Inf.py b/BaseTools/Source/Python/MigrationMsa2Inf/MigrationMsa2Inf.py new file mode 100644 index 0000000000..01de21239c --- /dev/null +++ b/BaseTools/Source/Python/MigrationMsa2Inf/MigrationMsa2Inf.py @@ -0,0 +1,2477 @@ +#!/usr/bin/env python +# +# +# Copyright (c) 2007, 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 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 program converts EDK II MSA files into EDK II Extended INF format files """ + +import os, re, sys, fnmatch, xml.dom.minidom +from optparse import OptionParser +from AutoGenExterns import * +from Common.XmlRoutines import * # XmlParseFile, XmlElement, XmlAttribute, XmlList, XmlElementData, XmlNode +from Common.EdkIIWorkspace import * + +versionNumber = "0.9" +__version__ = "%prog Version " + versionNumber +__copyright__ = "Copyright (c) 2007, Intel Corporation All rights reserved." + +commonHeaderFilename = "CommonHeader.h" +entryPointFilename = "EntryPoint.c" + +AutoGenLibraryMapping = { + "HiiLib":"HiiLibFramework", + "EdkIfrSupportLib":"IfrSupportLibFramework", + "EdkScsiLib":"ScsiLib", + "EdkUsbLib":"UsbLib", + "EdkFvbServiceLib":"FvbServiceLib", + "EdkGraphicsLib":"GraphicsLib" + } + +def myOptionParser(): + """ Argument Parser """ + usage = "%prog [options] -f input_filename" + parser = OptionParser(usage=usage,description=__copyright__,version="%prog " + str(versionNumber)) + parser.add_option("-f", "--file", dest="filename", help="Name of MSA file to convert") + parser.add_option("-o", "--output", dest="outfile", help="Specific Name of the INF file to create, otherwise it is the MSA filename with the extension repalced.") + parser.add_option("-a", "--auto", action="store_true", dest="autowrite", default=False, help="Automatically create output files and write the INF file") + parser.add_option("-i", "--interactive", action="store_true", dest="interactive", default=False, help="Set Interactive mode, user must approve each change.") + parser.add_option("-q", "--quiet", action="store_const", const=0, dest="verbose", help="Do not print any messages, just return either 0 for succes or 1 for failure") + parser.add_option("-v", "--verbose", action="count", dest="verbose", help="Do not print any messages, just return either 0 for succes or 1 for failure") + parser.add_option("-d", "--debug", action="store_true", dest="debug", default=False, help="Enable printing of debug messages.") + parser.add_option("-c", "--convert", action="store_true", dest="convert", default=False, help="Convert package: OldMdePkg->MdePkg EdkModulePkg->MdeModulePkg.") + parser.add_option("-e", "--event", action="store_true", dest="event", default=False, help="Enable handling of Exit Boot Services & Virtual Address Changed Event") + parser.add_option("-m", "--manual", action="store_true", dest="manual", default=False, help="Generate CommonHeader.txt, user picks up & copy it to a module common header") + parser.add_option("-w", "--workspace", dest="workspace", default=str(os.environ.get('WORKSPACE')), help="Specify workspace directory.") + (options, args) = parser.parse_args(sys.argv[1:]) + + return options,args + + +def openDatabase(f): + """ Parse XML in the FrameworkDatabase.db file pointed to by f """ + if (options.debug and options.verbose > 1): + print "Opening the database file:", f + if os.path.exists(f): + fdb = XmlParseFile(f) + else: + return "None" + return fdb + +def openSpd(s): + """ Parse XML in the SPD file pointed to by s """ + if (options.debug and options.verbose > 1): + print "Opening the SPD file:", s + if os.path.exists(s): + spd = XmlParseFile(s) + else: + return "None" + return spd + +def openMsa(m): + """ Parse XML in the MSA file pointed to by m """ + if (options.debug and options.verbose > 1): + print "Opening the MSA file:", m + if os.path.exists(m): + msa = XmlParseFile(m) + else: + return "None" + return msa + +def AddGuid(ArchList, CName, Usage): + """ Add a GUID to the Architecture array that the GUID is valid for. """ + if "IA32" in ArchList: + GuidCNameIa32.insert(0, str(" %-45s # %s" % (CName, Usage))) + if "X64" in ArchList: + GuidCNameX64.insert(0, str(" %-45s # %s" % (CName, Usage))) + if "IPF" in ArchList: + GuidCNameIPF.insert(0, str(" %-45s # %s" % (CName, Usage))) + if "EBC" in ArchList: + GuidCNameEBC.insert(0, str(" %-45s # %s" % (CName, Usage))) + if "ALL" in ArchList: + GuidCName.insert(0, str(" %-45s # %s" % (CName, Usage))) + + +def removeDups(CN, ListName): + """ Remove Duplicate Entries from the Guid List passed in """ + for Entry in ListName[:]: + if " " + CN + " " in Entry: + if (options.verbose > 1): + print "Removing C Name %s Entry from Guids List." % (CN) + ListName.remove(Entry) + +def chkArch(Archs): + """ Process the supported architectures passed in to combine if possible """ + Archs = Archs.upper() + if (("IA32" in Archs) & ("X64" in Archs) & ("IPF" in Archs) & ("EBC" in Archs)): + Archs = "ALL" + if (len(Archs) == 0): + Archs = "ALL" + return Archs + +def saveSourceFile(moduleDir, sourceFilename, sourceFileContents): + newFilename = os.path.join(moduleDir, sourceFilename) + + try: + f = open(newFilename, "w+") + f.write(sourceFileContents) + f.close() + except: + print "IO error in saving %s" % sourceFilename + + return sourceFilename + +def openSourceFile(moduleDir, sourceFilename): + newFilename = os.path.join(moduleDir, sourceFilename) + sourceFileContents = "" + try: + f = open(newFilename, "r") + sourceFileContents = f.read() + f.close() + except: + print "IO error in opening %s" % sourceFilename + + return sourceFileContents + +def MatchOption(eline, ToolChainFamily, Targets, Archs, ToolCode, Value): + IDs = eline.split("_") + + if len(IDs) < 5: + return [] + + MatchedTargets = [] + if (Targets[0] == "*") or IDs[0] in Targets: + MatchedTargets.append(IDs[0]) + elif IDs[0] == "*": + MatchedTargets = Targets + + MatchedArchs = [] + if Archs[0] == "*" or IDs[2] in Archs: + MatchedArchs.append(IDs[2]) + elif IDs[2] == "*": + MatchedArchs = Archs + + if IDs[3] != ToolCode and IDs[3] != "*": + return [] + + result = [] + for arch in MatchedArchs: + for target in MatchedTargets: + line = "%s:%s_%s_%s_%s_FLAGS = %s" % (ToolChainFamily, target, IDs[1], arch, ToolCode, Value) + result.append(line) + + return result + +def main(): + + AutoGenSource = "" + AutoGenHeader = "" + AutoGenDeclaration = "" + AutoGenModuleFolder = None + + workspace = "" + + if (options.workspace == None): + print "ERROR: E0000: WORKSPACE not defined.\n Please set the WORKSPACE environment variable to the location of the EDK II install directory." + sys.exit(1) + else: + workspace = options.workspace + if (options.debug): + print "Using Workspace:", workspace + + try: + options.verbose +=1 + except: + options.verbose = 1 + pass + + + FdbPath = os.path.join(workspace, "Conf") + FdbPath = os.path.join(FdbPath, "FrameworkDatabase.db") + if os.path.exists(FdbPath): + FdbFile = FdbPath + else: + print "ERROR: E0001: WORKSPACE does not contain the FrameworkDatabase File.\n Please run EdkSetup from the EDK II install directory.\n" + sys.exit(1) + + Fdb = openDatabase(FdbFile) + if (Fdb == 'None'): + print "ERROR: E0002 Could not open the Framework Database file:", FdbFile + sys.exit(1) + + if (options.debug): + print "FrameworkDataBase.db file:", FdbFile + + # + InitializeAutoGen(workspace, Fdb) + + if (options.filename): + filename = options.filename + if ((options.verbose > 1) | (options.autowrite)): + print "Filename:", filename + else: + print "ERROR: E0001 - You must specify an input filename" + sys.exit(1) + + if (options.outfile): + outputFile = options.outfile + else: + outputFile = filename.replace('.msa', '.inf') + + if ((options.verbose > 2) or (options.debug)): + print "Output Filename:", outputFile + + Msa = openMsa(filename) + if (Msa == 'None'): + ## Maybe developer think WORKSPACE macro is the root directory of file name + ## So we will try to add WORKSPACE path into filename + MsaFileName = "" + MsaFileName = os.path.join(workspace, filename) + Msa = openMsa(MsaFileName) + if (Msa == 'None'): + print "ERROR: E0002: Could not open the file:", filename + sys.exit(1) + + AutoGenModuleFolder = os.path.dirname(filename) + + MsaHeader = "/ModuleSurfaceArea/MsaHeader/" + MsaDefs = "/ModuleSurfaceArea/ModuleDefinitions/" + BaseName = str(XmlElement(Msa, MsaDefs + "OutputFileBasename")).strip() + + if (len(BaseName) < 1): + BaseName = str(XmlElement(Msa, MsaHeader + "BaseName")).strip() + BaseName = re.sub(' ', '_', BaseName) + + GuidValue = str(XmlElement(Msa, MsaHeader + "GuidValue")).strip() + VerString = str(XmlElement(Msa, MsaHeader + "Version")).strip() + ModType = str(XmlElement(Msa, MsaHeader + "ModuleType")).strip() + CopyRight = str(XmlElement(Msa, MsaHeader + "Copyright")).strip() + Abstract = str(XmlElement(Msa, MsaHeader + "Abstract")).strip() + Description = str(XmlElement(Msa, MsaHeader + "Description")).strip().replace(" ", " ").replace(" ", " ").replace(" ", " ") + if not CopyRight.find("2007"): + CopyRight = CopyRight.replace("2006", "2007") + License = str(XmlElement(Msa, MsaHeader + "License")).strip().replace(" ", " ") + MsaDefs = "/ModuleSurfaceArea/ModuleDefinitions/" + BinModule = "" + try: + BinModule = str(XmlElement(Msa, MsaDefs + "BinaryModule")).strip() + except: + pass + + SupportedArchitectures = "" + try: + SupportedArchitectures = str(XmlElement(Msa, MsaDefs + "SupportedArchitectures")).strip() + except: + pass + + DefinesComments = [] + if (len(SupportedArchitectures) > 0): + DefinesComments.insert(0, "\n#\n# The following information is for reference only and not required by the build tools.\n#\n") + DefinesComments.append("# VALID_ARCHITECTURES = " + SupportedArchitectures + "\n") + DefinesComments.append("#\n") + + MsaExtern = "/ModuleSurfaceArea/Externs/" + PcdIsDriver = "" + try: + PcdIsDriver = str(XmlElement(Msa, MsaExtern + "PcdIsDriver")).strip() + except: + pass + + SpecList = [] + List = [] + try: + List = XmlList(Msa, MsaExtern + "Specification") + except: + pass + + if (len(List) > 0): + for spec in List[:]: + SpecList.insert(0, str(XmlElementData(spec)).strip()) + + DriverModules = [] + LibraryModules = [] + Externlist = [] + Flag = (DefinesComments == []) + + # Data structure to insert autogen code + AutoGenDriverModel = [] + AutoGenExitBootServices = [] + AutoGenVirtualAddressChanged = [] + AutoGenEntryPoint = "" + AutoGenUnload = "" + AutoGenGuid = [] + AutoGenLibClass = [] + AutoGenPackage = [] + AutoGenSourceFiles = [] + OldEntryPoint = "" + OldUnload = "" + + try: + Externlist = XmlList(Msa, MsaExtern + "Extern") + except: + pass + + if (len(Externlist) > 0): + if (options.debug and options.verbose > 2): + print "In Extern Parsing Routine" + for extern in Externlist: + EntryPoint = "" + Unload = "" + DBinding = "" + CompName = "" + Diag = "" + Config = "" + Constr = "" + Destr = "" + CallBack = "" + lFlag = False + AutoGenDriverModelItem = [] + try: + EntryPoint = str(XmlElementData(extern.getElementsByTagName("ModuleEntryPoint")[0])).strip() + AutoGenEntryPoint = EntryPoint + #DriverModules.append(" %-30s = %s\n" % ("ENTRY_POINT" , EntryPoint)) + except: + pass + + try: + Unload = str(XmlElementData(extern.getElementsByTagName("ModuleUnloadImage")[0])).strip() + AutoGenUnload = Unload + DriverModules.append(" %-30s = %s\n" % ("UNLOAD_IMAGE", Unload)) + except: + pass + + try: + DBinding = str(XmlElementData(extern.getElementsByTagName("DriverBinding")[0])).strip() + AutoGenDriverModelItem.append("&" + DBinding) + DefinesComments.append("# %-29s = %-45s\n" % ("DRIVER_BINDING", DBinding)) + lFlag = True + except: + pass + + try: + CompName = str(XmlElementData(extern.getElementsByTagName("ComponentName")[0])).strip() + AutoGenDriverModelItem.append("&" + CompName) + DefinesComments.append("# %-29s = %-45s\n" % ("COMPONENT_NAME", CompName)) + lFlag = True + except: + if lFlag: + AutoGenDriverModelItem.append("NULL") + pass + + try: + Config = str(XmlElementData(extern.getElementsByTagName("DriverConfig")[0])).strip() + AutoGenDriverModelItem.append("&" + Config) + DefinesComments.append("# %-29s = %-45s\n" % ("DRIVER_CONFIG", Config)) + lFlag = True + except: + if lFlag: + AutoGenDriverModelItem.append("NULL") + pass + + try: + Diag = str(XmlElementData(extern.getElementsByTagName("DriverDiag")[0])).strip() + AutoGenDriverModelItem.append("&" + Diag) + DefinesComments.append("# %-29s = %-45s\n" % ("DRIVER_DIAG", Diag)) + lFlag = True + except: + if lFlag: + AutoGenDriverModelItem.append("NULL") + pass + + if len(AutoGenDriverModelItem) > 0: + AutoGenDriverModel.append(AutoGenDriverModelItem) + + try: + Constr = str(XmlElementData(extern.getElementsByTagName("Constructor")[0])).strip() + LibraryModules.append(" %-30s = %s\n" % ("CONSTRUCTOR", Constr)) + except: + pass + + try: + Destr = str(XmlElementData(extern.getElementsByTagName("Destructor")[0])).strip() + LibraryModules.append(" %-30s = %s\n" % ("DESTRUCTOR", Destr)) + except: + pass + + try: + CallBack = str(XmlElement(extern, "Extern/SetVirtualAddressMapCallBack")).strip() + if CallBack != "": + AutoGenVirtualAddressChanged.append(CallBack) + DefinesComments.append("# %-29s = %-45s\n" % ("VIRTUAL_ADDRESS_MAP_CALLBACK", CallBack)) + lFlag = True + except: + + pass + + try: + CallBack = str(XmlElement(extern, "Extern/ExitBootServicesCallBack")).strip() + if CallBack != "": + AutoGenExitBootServices.append(CallBack) + DefinesComments.append("# %-29s = %-45s\n" % ("EXIT_BOOT_SERVICES_CALLBACK", CallBack)) + lFlag = True + except: + pass + + + Flag = False + + """ Get the Module's custom build options """ + MBOlines = [] + MBO = "/ModuleSurfaceArea/ModuleBuildOptions/Options/Option" + mboList = [] + try: + mboList = XmlList(Msa, MBO) + except: + pass + + if (len(mboList) > 0): + for Option in mboList: + Targets = [] + Archs = [] + + bt = "" + try: + bt = str(Option.getAttribute("BuildTargets")) + except: + pass + + if (len(bt) > 0): + if (re.findall(" ", bt) > 0): + Targets = bt.split() + else: + Targets.insert(0, bt) + else: + Targets.insert(0, "*") + + if (options.debug and options.verbose > 2): + print "Targets", len(Targets), Targets + + pro = "" + try: + pro = Option.getAttribute("SupArchList") + if (re.findall(" ", pro) > 0): + Archs = pro.split() + elif (re.findall(",", pro) > 0): + Archs = pro.split(",") + except: + pass + + if (len(pro) == 0): + Archs.insert(0, "*") + + if (options.debug and options.verbose > 2): + print "Archs", len(Archs), Archs + + ToolCode = "" + try: + ToolCode = str(Option.getAttribute("ToolCode")) + except: + pass + + if (len(ToolCode) == 0): + ToolCode="*" + + value = "" + try: + value = str(XmlElementData(Option)) + except: + pass + Tags = [] + TagName = "" + try: + TagName = str(Option.getAttribute("TagName")) + except: + pass + + if (len(TagName) > 0) : + if (options.debug and options.verbose > 2): + print "TagName was defined:", TagName + Tags.insert(0, TagName) + else: + if (options.debug and options.verbose > 2): + print "TagName was NOT defined!" + TagName = "*" + Tags.insert(0, "*") + + Family = "" + try: + Family = str(Option.getAttribute("ToolChainFamily")).strip() + except: + pass + + if (len(Family) > 0): + if (options.debug): + print "Searching tools_def.txt for Tool Tags that belong to:", Family, "family" + TCF = [] + tdFile = "" + tdPath = os.path.join(workspace, "Tools") + tdPath = os.path.join(tdPath, "Conf") + tdPath = os.path.join(tdPath, "tools_def.txt") + tdPath = tdPath.replace("\\", "/") + if os.path.exists(tdPath): + tdFile = tdPath + else: + tdPath = os.path.join(workspace, "Conf") + tdPath = os.path.join(tdPath, "tools_def.txt") + if os.path.exists(tdPath): + tdFile = tdPath + else: + print "ERROR: E0001: WORKSPACE does not contain the tools_def.txt File.\n Please run EdkSetup from the EDK II install directory.\n" + sys.exit(1) + + if (options.debug and options.verbose > 2): + print "Opening:", tdFile + + TagNameList = [] + tools_def = open(tdFile, "r") + for tdline in tools_def: + if "# " in tdline: + continue + if "FAMILY" in tdline: + if (options.debug and options.verbose > 2): + print "Testing for FAMILY:", Family, "in the line:", tdline.strip() + if Family in tdline: + enter = tdline.split("=")[0] + if (options.debug and options.verbose > 2): + print "Adding TNL:", tdline + TagNameList.insert(0, enter) + tools_def.close() + + if (options.debug and options.verbose > 2): + print "TagNameList:", TagNameList + + olinesSet = {} + for eline in TagNameList: + if "# " in eline: + continue + if (options.debug and options.verbose > 2): + print "ToolsDef entry:", eline + + olines = MatchOption(eline, Family, Targets, Archs, ToolCode, value) + for oline in olines: + olinesSet[oline] = 1 + + for oline in olinesSet: + if (options.debug and options.verbose > 2): + print "Adding:", str(oline) + MBOlines.insert(0, oline) + else: + for targ in Targets: + for arch in Archs: + oline = " %s_%s_%s_%s_FLAGS = %s" % (targ, Tags[0], arch, str(ToolCode), str(Value)) + if (options.debug and options.verbose > 2): + print "Adding:", str(oline) + MBOlines.insert(0, oline) + + + + + for tag in Tags: + for targ in Targets: + for arch in Archs: + oline = " " + str(targ) + "_" + str(tag) + "_" + str(arch) + "_" + str(ToolCode) + "_FLAGS = " + str(value) + if (options.debug and options.verbose > 2): + print "Adding:", str(oline) + #MBOlines.insert(0, oline) + + + """ Get the Library Class information """ + MsaLcDefs = "/ModuleSurfaceArea/LibraryClassDefinitions/LibraryClass" + LcDefList = [] + try: + LcDefList = XmlList(Msa, MsaLcDefs) + except: + pass + + IamLibrary = [] + LibClassList = [] + LibClassListIa32 = [] + LibClassListX64 = [] + LibClassListIpf = [] + LibClassListEbc = [] + + + if (len(LcDefList) > 0): + for Lc in LcDefList: + lcKeyword = "" + try: + lcKeyword = str(XmlElementData(Lc.getElementsByTagName("Keyword")[0])) + except: + raise SyntaxError, "The MSA is not correctly formed, a Library Class Keyword Element is required" + + lcUsage = "" + try: + lcUsage = str(XmlAttribute(Lc, "Usage")) + except: + raise SyntaxError, "The MSA is not correctly formed, a Usage Attribute is required for all Library Class Elements" + + Archs = "" + try: + Archs = str(XmlAttribute(Lc, "SupArchList")) + except: + pass + + Archs = chkArch(Archs) + + if (options.debug and options.verbose > 2): + print "Attr: ", lcUsage, lcKeyword, Archs + + if (options.convert): + lcKeyword = AutoGenLibraryMapping.get(lcKeyword, lcKeyword) + + if re.findall("PRODUCED", lcUsage, re.IGNORECASE): + try: + lcSupModList = "" + + try: + lcSupModList = str(XmlAttribute(Lc, "SupModuleList")) + except: + lcSupModList = "" + pass + + lcLine = lcKeyword + AutoGenLibClass.append(lcKeyword) + if len(lcSupModList) > 0: + lcLine = lcLine + "|" + lcSupModList + IamLibrary.insert(0, lcLine) + except: + pass + elif lcKeyword != "UefiDriverModelLib": + AutoGenLibClass.append(lcKeyword) + # This section handles the library classes that are CONSUMED + if "IA32" in Archs: + LibClassListIa32.insert(0, lcKeyword) + if "X64" in Archs: + LibClassListX64.insert(0, lcKeyword) + if "IPF" in Archs: + LibClassListIpf.insert(0, lcKeyword) + if "EBC" in Archs: + LibClassListEbc.insert(0, lcKeyword) + if "ALL" in Archs: + LibClassList.insert(0, lcKeyword) + if len(AutoGenDriverModel) > 0 and "UefiLib" not in LibClassList: + AutoGenLibClass.append("UefiLib") + LibClassList.insert(0, "UefiLib") + + AutoGenDxsFiles = [] + """ Get the Source File list """ + SrcFilenames = [] + SrcFilenamesIa32 = [] + SrcFilenamesX64 = [] + SrcFilenamesIpf = [] + SrcFilenamesEbc = [] + SrcFiles = "/ModuleSurfaceArea/SourceFiles/Filename" + SrcList = [] + try: + SrcList = XmlList(Msa, SrcFiles) + except: + pass + + if (len(SrcList) > 0): + for fn in SrcList: + file = "" + Archs = "" + + try: + Archs = fn.getAttribute("SupArchList") + except: + pass + + Archs = chkArch(Archs) + + try: + file = str(XmlElementData(fn)) + except: + pass + + if file.endswith(".dxs"): + AutoGenDxsFiles.append((file, Archs)) + else: + AutoGenSourceFiles.append(file) + if "IA32" in Archs: + SrcFilenamesIa32.insert(0, file) + if "X64" in Archs: + SrcFilenamesX64.insert(0, file) + if "IPF" in Archs: + SrcFilenamesIpf.insert(0, file) + if "EBC" in Archs: + SrcFilenamesEbc.insert(0, file) + if "ALL" in Archs: + SrcFilenames.insert(0, file) + + """ Package Dependency section """ + DbPkgList = "/FrameworkDatabase/PackageList/Filename" + WorkspacePkgs = [] + try: + WorkspacePkgs = XmlList(Fdb, DbPkgList) + except: + print "Could not tet the package data from the database" + sys.exit(1) + + PkgDb = [] + HeaderLocations = [] + + if (options.debug and options.verbose > 1): + print "Found %s packages in the WORKSPACE" % (len(WorkspacePkgs)) + + Dirs = [] + GuidDecls = [] + if (len(WorkspacePkgs) > 0): + SpdHeader = "/PackageSurfaceArea/SpdHeader/" + for Pkg in WorkspacePkgs[:]: + PackageGuid = "" + PackageVersion = "" + file = "" + try: + file = str(XmlElementData(Pkg)) + except: + pass + + if (options.debug and options.verbose > 2): + print "PKG:", file + + if fnmatch.fnmatch(file, "*.dec"): + print "parsing " + os.path.join(workspace, file) + PackageGuid = "" + PackageVersion = "" + try: + Lines = open(os.path.join(workspace, file)).readlines() + except: + print "Could not parse the Package file:", file + sys.exit(1) + + for Line in Lines: + Line = Line.split("#")[0] + Items = Line.split("=") + if len(Items) != 2: + continue + + Key = Items[0].strip().upper() + if Key == "PACKAGE_GUID": + PackageGuid = Items[1].strip() + if Key == "PACKAGE_VERSION": + PackageVersion = Items[1].strip() + + else: + Spd = openSpd(os.path.join(workspace, file)) + if (Spd == 'None'): + print "Could not parse the Package file:", file + sys.exit(1) + + path = os.path.split(file)[0] + file = file.replace(".nspd", ".dec") + file = file.replace(".spd", ".dec") + + try: + PackageGuid = str(XmlElement(Spd, SpdHeader + "GuidValue")) + except: + pass + + try: + PackageVersion = str(XmlElement(Spd, SpdHeader + "Version")) + except: + pass + + file = file + "|" + PackageGuid + "|" + PackageVersion + PkgDb.insert(0, file) + + GuidEntries = [] + try: + GuidEntries = XmlList(Spd, "/PackageSurfaceArea/GuidDeclarations/Entry") + except: + pass + + if (len(GuidEntries) > 0): + for Entry in GuidEntries[:]: + try: + GuidDecls.append(str(XmlElementData(Entry.getElementsByTagName("C_Name")[0])).strip()) + except: + pass + + + pHdrs = [] + try: + pHdrs = XmlList(Spd, "/PackageSurfaceArea/PackageHeaders/IncludePkgHeader") + except: + pass + + if (len(pHdrs) > 0): + for Hdr in pHdrs[:]: + try: + ModTypeList = str(Hdr.getAttribute("ModuleType")) + if (ModType in ModTypeList): + HeaderName= str(XmlElementData(Hdr))[0] + Dirs.insert(0, os.path.join(packagepath,str(os.path.split(HeaderName)))) + except: + pass + + # Get the Guid:Header from the Packages + SpdLcDec = "/PackageSurfaceArea/LibraryClassDeclarations/LibraryClass" + lcList = [] + try: + lcList = XmlList(Spd, SpdLcDec) + except: + pass + + if (len(lcList) > 0): + for Lc in lcList[:]: + Name = "" + try: + Name = Lc.getAttribute("Name") + except: + pass + + Header = "" + try: + Header = XmlElementData(Lc.getElementsByTagName("IncludeHeader")[0]) + except: + pass + + if ((len(Name) > 0) and (len(Header) > 0)): + line = Name + "|" + os.path.join(path, Header) + if (options.debug and options.verbose > 2): + print "Adding:", line + HeaderLocations.insert(0, line) + + ishList = [] + try: + IndStdHeaders = "/PackageSurfaceArea/IndustryStdIncludes/IndustryStdHeader" + ishList = XmlList(Spd, IndStdHeaders) + except: + pass + + if (len(ishList) > 0): + for Lc in ishList[:]: + Name = "" + try: + Name = str(Lc.getAttribute("Name")).strip() + except: + pass + + Header = "" + try: + Header = str(XmlElementData(Lc.getElementsByTagName("IncludeHeader")[0])).strip() + except: + pass + + if ((len(Name) > 0) and (len(Header) > 0)): + line = Name + "|" + os.path.join(path, Header) + HeaderLocations.insert(0, str(line)) + + PkgList = [] + PkgListIa32 = [] + PkgListX64 = [] + PkgListIpf = [] + PkgListEbc = [] + Pkgs = "/ModuleSurfaceArea/PackageDependencies/Package" + pkgL = [] + try: + pkgL = XmlList(Msa, Pkgs) + except: + pass + + + gUnknownPkgGuid = {} + if (len(pkgL) > 0): + if (options.debug and options.verbose > 1): + print "Found %s packages in the module" % (len(pkgL)) + for pkg in pkgL[:]: + Archs = "" + pkgGuid = "" + pkgVer = "" + + FindPkgGuid = False + try: + Archs = pkg.getAttribute("SupArchList") + except: + pass + + Archs = chkArch(Archs) + + try: + pkgGuid = pkg.getAttribute("PackageGuid") + except: + pass + + if options.convert: + if pkgGuid.lower() == "5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec": + pkgGuid = "1E73767F-8F52-4603-AEB4-F29B510B6766" + if pkgGuid.lower() == "68169ab0-d41b-4009-9060-292c253ac43d": + pkgGuid = "BA0D78D6-2CAF-414b-BD4D-B6762A894288" + AutoGenPackage.append(pkgGuid) + try: + pkgVer = pkg.getAttribute("PackageVersion") + except: + pass + + for PkgEntry in PkgDb[:]: + if pkgGuid in PkgEntry: + if len(pkgVer) > 0: + if pkgVer in PkgEntry: + FindPkgGuid = True + if "IA32" in Archs: + PkgListIa32.insert(0, PkgEntry.split("|")[0]) + if "X64" in Archs: + PkgListX64.insert(0, PkgEntry.split("|")[0]) + if "IPF" in Archs: + PkgListIpf.insert(0, PkgEntry.split("|")[0]) + if "EBC" in Archs: + PkgListEbc.insert(0, PkgEntry.split("|")[0]) + if "ALL" in Archs: + PkgList.insert(0, PkgEntry.split("|")[0]) + else: + FindPkgGuid = True + if "IA32" in Archs: + PkgListIa32.insert(0, PkgEntry.split("|")[0]) + if "X64" in Archs: + PkgListX64.insert(0, PkgEntry.split("|")[0]) + if "IPF" in Archs: + PkgListIpf.insert(0, PkgEntry.split("|")[0]) + if "EBC" in Archs: + PkgListEbc.insert(0, PkgEntry.split("|")[0]) + if "ALL" in Archs: + PkgList.insert(0, PkgEntry.split("|")[0]) + + if not FindPkgGuid: + gUnknownPkgGuid[str(pkgGuid)] = 1 + + for UnknownPkgGuid in gUnknownPkgGuid: + print "Cannot resolve package dependency Guid:", UnknownPkgGuid + + PkgList.reverse() + PkgListIa32.reverse() + PkgListX64.reverse() + PkgListIpf.reverse() + PkgListEbc.reverse() + if (options.debug): + print "Package List:", PkgList + + + + """ Setup the Global GuidCName arrays that will hold data from various MSA locations """ + global GuidCName + global GuidCNameIa32 + global GuidCNameX64 + global GuidCNameIPF + global GuidCNameEBC + GuidCName = [] + GuidCNameIa32 = [] + GuidCNameX64 = [] + GuidCNameIPF = [] + GuidCNameEBC = [] + + """ Check for the GUIDs Element """ + Guids = "/ModuleSurfaceArea/Guids/GuidCNames" + GuidList = [] + try: + GuidList = XmlList(Msa, Guids) + except: + pass + + if (len(GuidList) > 0): + for Guid in GuidList: + Archs = "" + Usage = "" + CName = "" + + try: + Archs = Guid.getAttribute("SupArchList") + except: + pass + + Archs = chkArch(Archs) + + try: + Usage = Guid.getAttribute("Usage") + except: + pass + + try: + CName = str(XmlElementData(Guid.getElementsByTagName("GuidCName")[0])) + if CName in GuidDecls: + if (options.debug and options.verbose > 1): + print "Guids Adding Guid CName: %-45s # %s Archs: %s" % (CName, Usage, Archs) + AddGuid(Archs, CName, Usage) + AutoGenGuid.append(CName) + else: + raise AssertionError, "Guid %s defined in %s is not declared in any package (.dec) file!" % (CName, filename) + except: + pass + + if (options.debug and options.verbose > 2): + print "Guid C Name List:", GuidCName + + """ Check for Events """ + Guids = "/ModuleSurfaceArea/Events/CreateEvents/EventTypes" + GuidList = [] + try: + GuidList = XmlList(Msa, Guids) + except: + pass + + if (len(GuidList) > 0): + for Guid in GuidList: + Archs = "" + Usage = "" + CName = "" + + try: + Archs = Guid.getAttribute("SupArchList") + except: + pass + + Archs = chkArch(Archs) + + try: + Usage = Guid.getAttribute("Usage") + Type = str(XmlElementData(Guid.getElementsByTagName("EventType")[0])) + Usage += " Create Event: " + Type + except: + pass + + try: + CName = str(Guid.getAttribute("EventGuidCName")) + if CName in GuidDecls: + if (options.debug and options.verbose > 1): + print "CreateEvent Adding Guid CName: %-45s # %s Archs: %s" % (CName, Usage, Archs) + AddGuid(Archs, CName, Usage) + AutoGenGuid.append(CName) + else: + if (len(DefinesComments) == 0): + DefinesComments.insert(0, "\n#\n# The following information is for reference only and not required by the build tools.\n#\n") + DefinesComments.append("# Create Event Guid C Name: " + CName + " Event Type: " + Type + "\n") + Flag = True + except: + pass + + if (Flag): + DefinesComments.append("#\n") + Flag = False + + Guids = "/ModuleSurfaceArea/Events/SignalEvents/EventTypes" + GuidList = [] + try: + GuidList = XmlList(Msa, Guids) + except: + pass + + if (len(GuidList) > 0): + for Guid in GuidList: + Archs = "" + Usage = "" + CName = "" + + try: + Archs = Guid.getAttribute("SupArchList") + except: + pass + + Archs = chkArch(Archs) + + try: + Usage = Guid.getAttribute("Usage") + Type = str(XmlElementData(Guid.getElementsByTagName("EventType")[0])) + Usage += " Signal Event: " + Type + except: + pass + + try: + CName = str(Guid.getAttribute("EventGuidCName")) + if CName in GuidDecls: + if (options.debug and options.verbose > 1): + print "SignalEvent Adding Guid CName: %-45s # %s Archs: %s" % (CName, Usage, Archs) + AddGuid(Archs, CName, Usage) + AutoGenGuid.append(CName) + else: + if (len(DefinesComments) == 0): + DefinesComments.insert(0, "\n#\n# The following information is for reference only and not required by the build tools.\n#\n") + DefinesComments.append("# Signal Event Guid C Name: " + CName + " Event Type: " + Type + "\n") + Flag = True + except: + pass + + if (Flag): + DefinesComments.append("#\n") + Flag = False + + """ Check the HOB guids """ + Guids = "/ModuleSurfaceArea/Hobs/HobTypes" + GuidList = [] + try: + GuidList = XmlList(Msa, Guids) + except: + pass + + if (len(GuidList) > 0): + for Guid in GuidList: + Archs = "" + Usage = "" + CName = "" + + try: + Archs = Guid.getAttribute("SupArchList") + except: + pass + + Archs = chkArch(Archs) + + try: + Usage = Guid.getAttribute("Usage") + Type = str(XmlElementData(Guid.getElementsByTagName("HobType")[0])) + Usage += " Hob: " + Type + except: + pass + + try: + CName = str(Guid.getAttribute("HobGuidCName")) + if CName in GuidDecls: + if (options.debug and options.verbose > 1): + print "Hob Adding Guid CName: %-45s # %s Archs: %s" % (CName, Usage, Archs) + AddGuid(Archs, CName, Usage) + AutoGenGuid.append(CName) + else: + if (len(DefinesComments) == 0): + DefinesComments.insert(0, "\n#\n# The following information is for reference only and not required by the build tools.\n#\n") + DefinesComments.append("# HOB Guid C Name: " + CName + " Hob Type: " + Type + "\n") + Flag = True + except: + if (len(DefinesComments) == 0): + DefinesComments.insert(0, "\n#\n# The following information is for reference only and not required by the build tools.\n#\n") + DefinesComments.append("# HOB: " + Type + "\n") + Flag = True + pass + + if (Flag): + DefinesComments.append("#\n") + Flag = False + + """ Check for the SystemTables Element """ + Guids = "/ModuleSurfaceArea/SystemTables/SystemTableCNames" + GuidList = [] + try: + GuidList = XmlList(Msa, Guids) + except: + pass + + if (len(GuidList) > 0): + for Guid in GuidList: + Archs = "" + Usage = "" + CName = "" + + try: + Archs = Guid.getAttribute("SupArchList") + except: + pass + + Archs = chkArch(Archs) + + try: + Usage = Guid.getAttribute("Usage") + Usage += " System Table" + except: + pass + + try: + CName = str(XmlElementData(Guid.getElementsByTagName("SystemTableCName")[0])) + if (options.debug and options.verbose > 1): + print "System Table Adding Guid CName: %-45s # %s Archs: %s" % (CName, Usage, Archs) + AddGuid(Archs, CName, Usage) + AutoGenGuid.append(CName) + except: + pass + + """ Check for the DataHubs Element """ + Guids = "/ModuleSurfaceArea/DataHubs/DataHubRecord" + GuidList = [] + try: + GuidList = XmlList(Msa, Guids) + except: + pass + + if (len(GuidList) > 0): + for Guid in GuidList: + Archs = "" + Usage = "" + CName = "" + + try: + Archs = Guid.getAttribute("SupArchList") + except: + pass + + Archs = chkArch(Archs) + + try: + Usage = Guid.getAttribute("Usage") + Usage += " Data Hub" + except: + pass + + try: + CName = str(XmlElementData(Guid.getElementsByTagName("DataHubCName")[0])) + if (options.debug and options.verbose > 1): + print "Data Hub Adding Guid CName: %-45s # %s Archs: %s" % (CName, Usage, Archs) + AddGuid(Archs, CName, Usage) + AutoGenGuid.append(CName) + except: + pass + + """ Check for the HiiPackages Element """ + Guids = "/ModuleSurfaceArea/HiiPackages/HiiPackage" + GuidList = [] + try: + GuidList = XmlList(Msa, Guids) + except: + pass + + if (len(GuidList) > 0): + for Guid in GuidList: + Archs = "" + Usage = "" + CName = "" + + try: + Archs = Guid.getAttribute("SupArchList") + except: + pass + + Archs = chkArch(Archs) + + try: + Usage = Guid.getAttribute("Usage") + Usage += " HII Formset" + except: + pass + + try: + CName = str(XmlElementData(Guid.getElementsByTagName("HiiCName")[0])) + if (options.debug and options.verbose > 1): + print "Hii Formset Adding Guid CName: %-45s # %s Archs: %s" % (CName, Usage, Archs) + AddGuid(Archs, CName, Usage) + AutoGenGuid.append(CName) + except: + pass + + """ Check for the Variables Element """ + Guids = "/ModuleSurfaceArea/Variables/Variable" + GuidList = [] + try: + GuidList = XmlList(Msa, Guids) + except: + pass + + if (len(GuidList) > 0): + for Guid in GuidList: + Archs = "" + Usage = "" + CName = "" + VariableName = "" + + try: + Archs = Guid.getAttribute("SupArchList") + except: + pass + + Archs = chkArch(Archs) + + try: + Usage = Guid.getAttribute("Usage") + except: + pass + + try: + VariableName = str(XmlElementData(Guid.getElementsByTagName("VariableName")[0])) + CName = str(XmlElementData(Guid.getElementsByTagName("GuidC_Name")[0])) + + HexData = VariableName.strip().split() + UniString = " L\"" + for dig in HexData[:]: + UniString += str(unichr(eval(dig))) + UniString += "\"" + + Usage += UniString + + if CName in set(GuidDecls): + removeDups(CName, GuidCName) + removeDups(CName, GuidCNameIa32) + removeDups(CName, GuidCNameX64) + removeDups(CName, GuidCNameIPF) + removeDups(CName, GuidCNameEBC) + + if (options.debug): + print "Variable Adding Guid CName: %-45s # %s Archs: %s" % (CName, Usage, Archs) + AddGuid(Archs, CName, Usage) + AutoGenGuid.append(CName) + else: + if (len(DefinesComments) == 0): + DefinesComments.insert(0, "\n#\n# The following information is for reference only and not required by the build tools.\n#\n") + DefinesComments.append("# Variable Guid C Name: " + CName + " Variable Name:" + UniString + "\n") + Flag = True + except: + pass + + if (Flag): + DefinesComments.append("#\n") + Flag = False + + """ Check for the Protocol Element """ + Protocols = "/ModuleSurfaceArea/Protocols/Protocol" + ProtocolList = [] + ProtocolCName = [] + ProtocolCNameIa32 = [] + ProtocolCNameX64 = [] + ProtocolCNameIPF = [] + ProtocolCNameEBC = [] + + try: + ProtocolList = XmlList(Msa, Protocols) + except: + pass + + if (len(ProtocolList) > 0): + for Protocol in ProtocolList: + Archs = "" + Usage = "" + CName = "" + + try: + Archs = Protocol.getAttribute("SupArchList") + except: + pass + + Archs = chkArch(Archs) + + try: + Usage = Protocol.getAttribute("Usage") + except: + pass + + try: + CName = str(XmlElementData(Protocol.getElementsByTagName("ProtocolCName")[0])) + AutoGenGuid.append(CName) + removeDups(CName, GuidCName) + removeDups(CName, GuidCNameIa32) + removeDups(CName, GuidCNameX64) + removeDups(CName, GuidCNameIPF) + removeDups(CName, GuidCNameEBC) + + if (options.debug and options.verbose > 1): + print "Found %s - %s - %s " % (CName, Usage, str(len(Archs))) + + if "IA32" in Archs: + ProtocolCNameIa32.insert(0, str(" %-45s # PROTOCOL %s" % (CName, Usage))) + if "X64" in Archs: + ProtocolCNameX64.insert(0, str(" %-45s # PROTOCOL %s" % (CName, Usage))) + if "IPF" in Archs: + ProtocolCNameIPF.insert(0, str(" %-45s # PROTOCOL %s" % (CName, Usage))) + if "EBC" in Archs: + ProtocolCNameEBC.insert(0, str(" %-45s # PROTOCOL %s" % (CName, Usage))) + if "ALL" in Archs: + ProtocolCName.insert(0, str(" %-45s # PROTOCOL %s" % (CName, Usage))) + except: + pass + + + Protocols = "/ModuleSurfaceArea/Protocols/ProtocolNotify" + try: + ProtocolList = XmlList(Msa, Protocols) + except: + pass + + if (len(ProtocolList) > 0): + for Protocol in ProtocolList: + Archs = "" + Usage = "" + CName = "" + + try: + Archs = Protocol.getAttribute("SupArchList") + except: + pass + + Archs = chkArch(Archs) + + try: + Usage = Protocol.getAttribute("Usage") + except: + pass + + try: + CName = str(XmlElementData(Protocol.getElementsByTagName("ProtocolNotifyCName")[0])) + AutoGenGuid.append(CName) + removeDups(CName, GuidCName) + removeDups(CName, GuidCNameIa32) + removeDups(CName, GuidCNameX64) + removeDups(CName, GuidCNameIPF) + removeDups(CName, GuidCNameEBC) + + if "IA32" in Archs: + ProtocolCNameIa32.insert(0, " %-45s # PROTOCOL_NOTIFY %s" % (CName, Usage)) + if "X64" in Archs: + ProtocolCNameX64.insert(0, " %-45s # PROTOCOL_NOTIFY %s" % (CName, Usage)) + if "IPF" in Archs: + ProtocolCNameIPF.insert(0, " %-45s # PROTOCOL_NOTIFY %s" % (CName, Usage)) + if "EBC" in Archs: + ProtocolCNameEBC.insert(0, " %-45s # PROTOCOL_NOTIFY %s" % (CName, Usage)) + if "ALL" in Archs: + ProtocolCName.insert(0, " %-45s # PROTOCOL_NOTIFY %s" % (CName, Usage)) + except: + pass + + """ Check for the PPIs Element """ + PPIs = "/ModuleSurfaceArea/PPIs/Ppi" + PPIsList = [] + PpiCName = [] + PpiCNameIa32 = [] + PpiCNameX64 = [] + PpiCNameIPF = [] + PpiCNameEBC = [] + + try: + PPIsList = XmlList(Msa, PPIs) + except: + pass + + if (len(PPIsList) > 0): + for Ppi in PPIsList: + Archs = "" + Usage = "" + CName = "" + + try: + Archs = str(Ppi.getAttribute("SupArchList")) + except: + pass + + Archs = chkArch(Archs) + + try: + Usage = str(Ppi.getAttribute("Usage")) + except: + pass + + try: + CName = str(XmlElementData(Ppi.getElementsByTagName("PpiCName")[0])).strip() + AutoGenGuid.append(CName) + removeDups(CName, GuidCName) + removeDups(CName, GuidCNameIa32) + removeDups(CName, GuidCNameX64) + removeDups(CName, GuidCNameIPF) + removeDups(CName, GuidCNameEBC) + + if "IA32" in Archs: + PpiCNameIa32.insert(0, " %-45s # PPI %s" % (CName, Usage)) + if "X64" in Archs: + PpiCNameX64.insert(0, " %-45s # PPI %s" % (CName, Usage)) + if "IPF" in Archs: + PpiCNameIPF.insert(0, " %-45s # PPI %s" % (CName, Usage)) + if "EBC" in Archs: + PpiCNameEBC.insert(0, " %-45s # PPI %s" % (CName, Usage)) + if "ALL" in Archs: + PpiCName.insert(0, " %-45s # PPI %s" % (CName, Usage)) + except: + pass + + + PPIs = "/ModuleSurfaceArea/PPIs/PpiNotify" + try: + PPIsList = XmlList(Msa, PPIs) + except: + pass + + if (len(PPIsList) > 0): + for Ppi in PPIsList: + Archs = "" + Usage = "" + CName = "" + + try: + Archs = Ppi.getAttribute("SupArchList") + except: + pass + + Archs = chkArch(Archs) + + try: + Usage = Ppi.getAttribute("Usage") + except: + pass + + try: + CName = str(XmlElementData(Ppi.getElementsByTagName("PpiNotifyCName")[0])) + AutoGenGuid.append(CName) + removeDups(CName, GuidCName) + removeDups(CName, GuidCNameIa32) + removeDups(CName, GuidCNameX64) + removeDups(CName, GuidCNameIPF) + removeDups(CName, GuidCNameEBC) + + if "IA32" in Archs: + PpiCNameIa32.insert(0, " %-45s # PPI_NOTIFY %s" % (CName, Usage)) + if "X64" in Archs: + PpiCNameX64.insert(0, " %-45s # PPI_NOTIFY %s" % (CName, Usage)) + if "IPF" in Archs: + PpiCNameIPF.insert(0, " %-45s # PPI_NOTIFY %s" % (CName, Usage)) + if "EBC" in Archs: + PpiCNameEBC.insert(0, " %-45s # PPI_NOTIFY %s" % (CName, Usage)) + if "ALL" in Archs: + PpiCName.insert(0, " %-45s # PPI_NOTIFY %s" % (CName, Usage)) + except: + pass + + + """ Get the PCD entries now """ + PcdCoded = "/ModuleSurfaceArea/PcdCoded/PcdEntry" + PcdList = [] + try: + PcdList = XmlList(Msa, PcdCoded) + except: + pass + + (PcdFF, PcdFFIa32, PcdFFX64, PcdFFIpf, PcdFFEbc) = ([],[],[],[],[]) + (PcdFAB, PcdFABIa32, PcdFABX64, PcdFABIpf, PcdFABEbc) = ([],[],[],[],[]) + (PcdPIM, PcdPIMIa32, PcdPIMX64, PcdPIMIpf, PcdPIMEbc) = ([],[],[],[],[]) + (PcdDY, PcdDYIa32, PcdDYX64, PcdDYIpf, PcdDYEbc) = ([],[],[],[],[]) + (PcdDYE, PcdDYEIa32, PcdDYEX64, PcdDYEIpf, PcdDYEEbc) = ([],[],[],[],[]) + + if (len(PcdList) > 0): + for Pcd in PcdList: + Archs = "" + Usage = "" + CName = "" + DefVal = "" + + try: + Archs = Pcd.getAttribute("SupArchList") + except: + pass + + Archs = chkArch(Archs) + + try: + ItemType = Pcd.getAttribute("PcdItemType") + except: + pass + + try: + CName = str(XmlElementData(Pcd.getElementsByTagName("C_Name")[0])) + except: + raise SyntaxError, "ERROR: MSA has a PCD with no Pcd C_Name defined" + + try: + TSGC = str(XmlElementData(Pcd.getElementsByTagName("TokenSpaceGuidCName")[0])) + except: + pass + + try: + DefVal = str(XmlElementData(Pcd.getElementsByTagName("DefaultValue"))) + except: + pass + + if (len(DefVal) > 0): + line = TSGC + "." + CName + "|" + DefVal + else: + line = TSGC + "." + CName + + if (ItemType == "FEATURE_FLAG"): + if ("IA32" in Archs): + PcdFFIa32.insert(0, line) + if ("IPF" in Archs): + PcdFFIpf.insert(0, line) + if ("X64" in Archs): + PcdFFX64.insert(0, line) + if ("EBC" in Archs): + PcdFFEbc.insert(0, line) + if ("ALL" in Archs): + PcdFF.insert(0, line) + elif (ItemType == "FIXED_AT_BUILD"): + if ("IA32" in Archs): + PcdFABIa32.insert(0, line) + if ("IPF" in Archs): + PcdFABIpf.insert(0, line) + if ("X64" in Archs): + PcdFABX64.insert(0, line) + if ("EBC" in Archs): + PcdFABEbc.insert(0, line) + if ("ALL" in Archs): + PcdFAB.insert(0, line) + elif (ItemType == "PATCHABLE_IN_MODULE"): + if ("IA32" in Archs): + PcdPIMIa32.insert(0, line) + if ("IPF" in Archs): + PcdPIMIpf.insert(0, line) + if ("X64" in Archs): + PcdPIMX64.insert(0, line) + if ("EBC" in Archs): + PcdPIMEbc.insert(0, line) + if ("ALL" in Archs): + PcdFAB.insert(0, line) + elif (ItemType == "DYNAMIC_EX"): + if ("IA32" in Archs): + PcdDYEIa32.insert(0, line) + if ("IPF" in Archs): + PcdDYEIpf.insert(0, line) + if ("X64" in Archs): + PcdDYEX64.insert(0, line) + if ("EBC" in Archs): + PcdDYEEbc.insert(0, line) + if ("ALL" in Archs): + PcdDYE.insert(0, line) + else: + if ("IA32" in Archs): + PcdDYIa32.insert(0, line) + if ("IPF" in Archs): + PcdDYIpf.insert(0, line) + if ("X64" in Archs): + PcdDYX64.insert(0, line) + if ("EBC" in Archs): + PcdDYEbc.insert(0, line) + if ("ALL" in Archs): + PcdDY.insert(0, line) + + """ User Extensions Section """ + UEList = [] + UESectionList = [] + try: + UESectionList = XmlList(Msa, "/ModuleSurfaceArea/UserExtensions") + except: + pass + + if (len(UESectionList) > 0): + for UE in UESectionList[:]: + UserId = "" + Identifier = "" + Value = "" + + try: + UserId = str(UE.getAttribute("UserID")) + except: + raise SyntaxError, "ERROR: Malformed MSA, No UserID Specified in UserExtensions element" + + try: + Identifier = str(UE.getAttribute("Identifier")) + except: + raise SyntaxError, "ERROR: Malformed MSA, No Identifier Specified in UserExtensions element" + + if (options.debug): + print "FOUND A UE Element", UserId, Identifier + + try: + Value = str(XmlElementData(UE)) + except: + pass + + Entry = [UserId, Identifier, Value] + UEList.insert(0, Entry) + + + + if (len(Externlist) > 0): + AutoGenSource = "" + AutoGenDefinitionSource = "" + AutoGenEntryPointSource = "" + AutoGenUnloadSource = "" + if (len(AutoGenDriverModel) > 0): + AutoGenCode = AddDriverBindingProtocolStatement(AutoGenDriverModel) + AutoGenEntryPointSource += AutoGenCode[0] + AutoGenUnloadSource += AutoGenCode[1] + AutoGenDeclaration += AutoGenCode[3] + + + if (len(AutoGenExitBootServices) > 0): + print "[Warning] Please manually add Create Event statement for Exit Boot Service Event!" + if options.event: + AutoGenCode = AddBootServiceEventStatement(AutoGenExitBootServices) + AutoGenEntryPointSource += AutoGenCode[0] + AutoGenUnloadSource += AutoGenCode[1] + AutoGenDefinitionSource += AutoGenCode[2] + AutoGenDeclaration += AutoGenCode[3] + + if (len(AutoGenVirtualAddressChanged) > 0): + print "[Warning] Please manually add Create Event statement for Virtual Address Change Event!" + if options.event: + AutoGenCode = AddVirtualAddressEventStatement(AutoGenVirtualAddressChanged) + AutoGenEntryPointSource += AutoGenCode[0] + AutoGenUnloadSource += AutoGenCode[1] + AutoGenDefinitionSource += AutoGenCode[2] + AutoGenDeclaration += AutoGenCode[3] + + if AutoGenEntryPointSource != "": + OldEntryPoint = AutoGenEntryPoint + AutoGenCode = AddNewEntryPointContentsStatement(BaseName, AutoGenEntryPoint, AutoGenEntryPointSource) + AutoGenEntryPoint = AutoGenCode[0] + AutoGenEntryPointSource = AutoGenCode[1] + AutoGenDeclaration += AutoGenCode[2] + + + if AutoGenEntryPoint != "": + DriverModules.insert(0, " %-30s = %s\n" % ("ENTRY_POINT" , AutoGenEntryPoint)) + + AutoGenSource = AutoGenDefinitionSource + AutoGenEntryPointSource + AutoGenUnloadSource + + if (lFlag): + DefinesComments.append("#\n") + + if (Flag and len(DefinesComments) > 0): + DefinesComments.insert(0, "\n#\n# The following information is for reference only and not required by the build tools.\n#\n") + + if (options.debug and options.verbose > 2): + if (len(DriverModules) > 0): + print DriverModules + if (len(LibraryModules) > 0): + print LibraryModules + if (len(DefinesComments) > 0): + print DefinesComments + + Depex = [] + DepexIa32 = [] + DepexX64 = [] + DepexIpf = [] + DepexEbc = [] + + for DxsFile, Archs in AutoGenDxsFiles: + fileContents = openSourceFile(AutoGenModuleFolder, DxsFile) + Contents, Unresolved = TranslateDpxSection(fileContents) + if Contents == "": + print "[warning] Cannot read dxs expression" + else: + if (len(Unresolved) > 0): + print "[warning] Guid Macro(s): %s cannot find corresponding cNames. Please resolve it in [depex] section in extened inf" % ",".join(Unresolved) + + if ("IA32" in Archs): + DepexIa32.insert(0, Contents) + if ("IPF" in Archs): + DepexIpf.insert(0, Contents) + if ("X64" in Archs): + DepexX64.insert(0, Contents) + if ("EBC" in Archs): + DepexEbc.insert(0, Contents) + if ("ALL" in Archs): + Depex.insert(0, Contents) + + AutoGenSourceHeaderFormat = "/**@file\n %s\n\n %s\n %s\n %s\n**/\n\n%s" + includeCommonHeaderFileStatement = "#include \"%s\"" % commonHeaderFilename + + AutoGenHeader += AddSystemIncludeStatement(ModType, AutoGenPackage) + AutoGenHeader += AddGuidStatement(AutoGenGuid) + AutoGenHeader += AddLibraryClassStatement(AutoGenLibClass) + + if options.manual: + saveSourceFile(AutoGenModuleFolder, "CommonHeader.txt", AutoGenHeader) + else: + + commonHeaderFilename2 = re.sub("(?=[^a-z])", "_", commonHeaderFilename) + commonHeaderFilename2 = "_" + commonHeaderFilename2.replace(".", "").upper() + "_" + briefDiscription = "Common header file shared by all source files." + detailedDiscription = "This file includes package header files, library classes and protocol, PPI & GUID definitions.\n" + AutoGenHeader += AutoGenDeclaration + AutoGenHeader = "#ifndef %s\n#define %s\n\n\n%s\n#endif\n" % (commonHeaderFilename2, commonHeaderFilename2, AutoGenHeader) + AutoGenHeader = AutoGenSourceHeaderFormat % (briefDiscription, detailedDiscription, CopyRight, License, AutoGenHeader) + saveSourceFile(AutoGenModuleFolder, commonHeaderFilename, AutoGenHeader) + SrcFilenames.append(commonHeaderFilename) + + for source in AutoGenSourceFiles: + extension = os.path.splitext(source)[1] + if extension == ".c": + sourceContents = openSourceFile(AutoGenModuleFolder, source) + sourceContents = AddCommonInclusionStatement(sourceContents, includeCommonHeaderFileStatement) + saveSourceFile(AutoGenModuleFolder, source, sourceContents) + + + if AutoGenSource != "": + briefDiscription = "Entry Point Source file." + detailedDiscription = "This file contains the user entry point \n" + AutoGenSource = AutoGenSourceHeaderFormat % (briefDiscription, detailedDiscription, CopyRight, License, AutoGenSource) + AutoGenSource = AddCommonInclusionStatement(AutoGenSource, includeCommonHeaderFileStatement) + + saveSourceFile(AutoGenModuleFolder, entryPointFilename, AutoGenSource) + SrcFilenames.append(entryPointFilename) + + + + + # DONE Getting data, now output it in INF format. + Msa.unlink() + Fdb.unlink() + Output = [] + + """ Print the converted data format """ + head = "#/** @file\n" + head += "# " + str(Abstract) + "\n#\n" + head += "# " + str(Description).strip().replace("\n", "\n# ") + "\n" + head += "# " + str(CopyRight) + "\n#\n" + head += "# " + str(License).replace("\n", "\n# ").replace(" ", " ").strip() + "\n#\n" + head += "#\n#**/\n" + + Output.append(head) + if (options.debug): + print head + +## Defines = "\n" + "#"*80+ "\n#\n" +## if (BinModule != "false"): +## Defines += "# Defines Section - statements that will be processed to generate a binary image.\n" +## else: +## Defines += "# Defines Section - statements that will be processed to create a Makefile.\n" +## Defines += "#\n" + "#"*80 + "\n" + + Defines = "\n" + Defines += "[Defines]\n" + Defines += " %-30s = %s\n" % ("INF_VERSION", "0x00010005") + Defines += " %-30s = %s\n" % ("BASE_NAME", BaseName) + Defines += " %-30s = %s\n" % ("FILE_GUID", GuidValue) + Defines += " %-30s = %s\n" % ("MODULE_TYPE", ModType) + Defines += " %-30s = %s\n" % ("VERSION_STRING", VerString) + + if (len(PcdIsDriver) > 0): + Defines += " %-30s = %s\n" % ("PCD_DRIVER", PcdIsDriver) + + if (len(IamLibrary) > 0): + lcstr = "" + for lc in IamLibrary[:]: + lcstr += lc + " " + Defines += " %-30s = %s" % ("LIBRARY_CLASS", lcstr) + Defines += "\n" + + if (len(SpecList) > 0): + for spec in SpecList[:]: + (specname, specval) = spec.split() + Defines += " %-30s = %s\n" % (specname, specval) + Defines += "\n" + + if (len(DriverModules) > 0): + for line in DriverModules[:]: + Defines += line + + if (len(LibraryModules) > 0): + for line in LibraryModules[:]: + Defines += line + + if (len(DefinesComments) > 0): + for line in DefinesComments[:]: + Defines += line + + Output.append(Defines) + + if (options.debug): + print Defines + + if (BinModule != "false"): + """ Binary Module, so sources are really binaries. """ +## Sources = "\n" + "#"*80 + "\n#\n" +## Sources += "# Binaries Section - list of binary files that are required for the build\n# to succeed.\n" +## Sources += "#\n" + "#"*80 + "\n\n" + Sources = "\n" + if ModType == "UEFI_APPLICATION": + FileType = "UEFI_APP" + if options.verbose > 0: + print "WARNING: Binary Module: %s is assuming UEFI_APPLICATION file type." % (options.filename) + else: + FileType = "FV" + if options.verbose > 0: + print "WARNING: Binary Module: %s is assuming FV file type." % (options.filename) + + if (len(SrcFilenames) > 0): + Sources += "[Binaries.common]\n" + for file in SrcFilenames[:]: + file = file.replace("\\", "/") + Sources += " " + FileType + "|" + file + "\n" + Sources += "\n" + + if (len(SrcFilenamesIa32) > 0): + Sources += "[Binaries.Ia32]\n" + for file in SrcFilenamesIa32[:]: + file = file.replace("\\", "/") + Sources += " " + FileType + "|" + file + "\n" + Sources += "\n" + + if (len(SrcFilenamesX64) > 0): + Sources += "[Binaries.X64]\n" + for file in SrcFilenamesX64[:]: + file = file.replace("\\", "/") + Sources += " " + FileType + "|" + file + "\n" + Sources += "\n" + + if (len(SrcFilenamesIpf) > 0): + Sources += "[Binaries.IPF]\n" + for file in SrcFilenamesIpf[:]: + file = file.replace("\\", "/") + Sources += " " + FileType + "|" + file + "\n" + Sources += "\n" + + if (len(SrcFilenamesEbc) > 0): + Sources += "[Binaries.EBC]\n" + for file in SrcFilenamesEbc[:]: + file = file.replace("\\", "/") + Sources += " " + FileType + "|" + file + "\n" + Sources += "\n" + + Output.append(Sources) + if (options.debug): + print Sources + else: +## Sources = "\n" + "#"*80 + "\n#\n" +## Sources += "# Sources Section - list of files that are required for the build to succeed.\n" +## Sources += "#\n" + "#"*80 + "\n\n" + Sources = "\n" + if (len(SrcFilenames) > 0): + Sources += "[Sources.common]\n" + for file in SrcFilenames[:]: + Sources += " " + file + "\n" + Sources += "\n" + + if (len(SrcFilenamesIa32) > 0): + Sources += "[Sources.Ia32]\n" + for file in SrcFilenamesIa32[:]: + Sources += " " + file + "\n" + Sources += "\n" + + if (len(SrcFilenamesX64) > 0): + Sources += "[Sources.X64]\n" + for file in SrcFilenamesX64[:]: + Sources += " " + file + "\n" + Sources += "\n" + + if (len(SrcFilenamesIpf) > 0): + Sources += "[Sources.IPF]\n" + for file in SrcFilenamesIpf[:]: + Sources += " " + file + "\n" + Sources += "\n" + + if (len(SrcFilenamesEbc) > 0): + Sources += "[Sources.EBC]\n" + for file in SrcFilenamesEbc[:]: + Sources += " " + file + "\n" + Sources += "\n" + + Output.append(Sources) + if (options.debug): + print Sources + + + includeLine = "" + if ((len(HeaderLocations) > 0) or (len(Dirs) > 0)): + allLcs = set(LibClassList + LibClassListIa32 + LibClassListX64 + LibClassListIpf + LibClassListEbc + Dirs) + Lines = [] + for line in HeaderLocations[:]: + for Lc in allLcs: + (keyword, header) = line.split("|") + if Lc in keyword: + if (options.debug): + print "FOUND", Lc, "in", keyword, "header", header + path = "$(WORKSPACE)/" + os.path.split(header)[0] + Lines.insert(0, path.strip()) + Includes = "" +## Includes = "\n" + "#"*80 + "\n#\n" +## Includes += "# Includes Section - list of Include locations that are required for\n" +## Includes += "# this module.\n" +## Includes += "#\n" + "#"*80 + "\n\n" +## Includes += "[Includes]\n" +## includeLines = [] +## includeLines = set(Lines) +## if (options.debug): +## print "There are", len(includeLines), "entries" +## for Line in includeLines: +## Includes += " " + str(Line).strip().replace("\\", "/") + "\n" + + Output.append(Includes) + if (options.debug): + print Includes + + + + if ((len(PkgList) + len(PkgListIa32) + len(PkgListX64) + len(PkgListIpf) + len(PkgListEbc)) > 0): + """ We do this if and only if we have Package Dependencies """ +## PackageDepends = "\n" + "#"*80 + "\n#\n" +## PackageDepends += "# Package Dependency Section - list of Package files that are required for\n" +## PackageDepends += "# this module.\n" +## PackageDepends += "#\n" + "#"*80 + "\n\n" + PackageDepends = "\n" + if (len(PkgList) > 0): + PackageDepends += "[Packages]\n" + for lc in PkgList[:]: + lc = lc.replace("\\", "/") + PackageDepends += " " + lc + "\n" + PackageDepends += "\n" + + if (len(PkgListIa32) > 0): + PackageDepends += "[Packages.IA32]\n" + for lc in PkgListIa32[:]: + lc = lc.replace("\\", "/") + PackageDepends += " " + lc + "\n" + PackageDepends += "\n" + + if (len(PkgListX64) > 0): + PackageDepends += "[Packages.X64]\n" + for lc in PkgListX64[:]: + lc = lc.replace("\\", "/") + PackageDepends += " " + lc + "\n" + PackageDepends += "\n" + + if (len(PkgListIpf) > 0): + PackageDepends += "[Packages.IPF]\n" + for lc in PkgListIpf[:]: + lc = lc.replace("\\", "/") + PackageDepends += " " + lc + "\n" + PackageDepends += "\n" + + if (len(PkgListEbc) > 0): + PackageDepends += "[Packages.EBC]\n" + for lc in PkgListEbc[:]: + lc = lc.replace("\\", "/") + PackageDepends += " " + lc + "\n" + PackageDepends += "\n" + + Output.append(PackageDepends) + if (options.debug): + print PackageDepends + + if ((len(LibClassList) + len(LibClassListIa32) + len(LibClassListX64) + len(LibClassListIpf) + len(LibClassListEbc)) > 0): +## LibraryClasses = "\n" + "#"*80 + "\n#\n" +## LibraryClasses += "# Library Class Section - list of Library Classes that are required for\n" +## LibraryClasses += "# this module.\n" +## LibraryClasses += "#\n" + "#"*80 + "\n\n" + + LibraryClasses = "\n" + if (len(LibClassList) > 0): + LibraryClasses += "[LibraryClasses]\n" + for lc in LibClassList[:]: + LibraryClasses += " " + lc + "\n" + LibraryClasses += "\n" + + if (len(LibClassListIa32) > 0): + LibraryClasses += "[LibraryClasses.IA32]\n" + for lc in LibClassListIa32[:]: + LibraryClasses += " " + lc + "\n" + LibraryClasses += "\n" + + if (len(LibClassListX64) > 0): + LibraryClasses += "[LibraryClasses.X64]\n" + for lc in LibClassListX64[:]: + LibraryClasses += " " + lc + "\n" + LibraryClasses += "\n" + + if (len(LibClassListIpf) > 0): + LibraryClasses += "[LibraryClasses.IPF]\n" + for lc in LibClassListIpf[:]: + LibraryClasses += " " + lc + "\n" + LibraryClasses += "\n" + + if (len(LibClassListEbc) > 0): + LibraryClasses += "[LibraryClasses.EBC]\n" + for lc in LibClassListEbc[:]: + LibraryClasses += " " + lc + "\n" + LibraryClasses += "\n" + + Output.append(LibraryClasses) + if (options.debug): + print LibraryClasses + + # Print the Guids sections + if (len(GuidCName) + len(GuidCNameIa32) + len(GuidCNameIPF) + len(GuidCNameX64) + len(GuidCNameEBC)) > 0: +## GuidSection = "\n" + "#"*80 + "\n#\n" +## GuidSection += "# Guid C Name Section - list of Guids that this module uses or produces.\n" +## GuidSection += "#\n" + "#"*80 + "\n\n" + GuidSection = "\n" + if (len(GuidCName) > 0): + GuidSection += "[Guids]\n" + for Guid in GuidCName[:]: + GuidSection += Guid + "\n" + GuidSection += "\n" + + if (len(GuidCNameIa32) > 0): + GuidSection += "[Guids.IA32]\n" + for Guid in GuidCNameIa32[:]: + GuidSection += Guid + "\n" + GuidSection += "\n" + + if (len(GuidCNameX64) > 0): + GuidSection += "[Guids.X64]\n" + for Guid in GuidCNameX64[:]: + GuidSection += Guid + "\n" + GuidSection += "\n" + + if (len(GuidCNameIPF) > 0): + GuidSection += "[Guids.IPF]\n" + for Guid in GuidCNameIPF[:]: + GuidSection += Guid + "\n" + GuidSection += "\n" + + if (len(GuidCNameEBC) > 0): + GuidSection += "[Guids.EBC]\n" + for Guid in GuidCNameEBC[:]: + GuidSection += Guid + "\n" + GuidSection += "\n" + + Output.append(GuidSection) + if (options.debug and options.verbose > 1): + print GuidSection + + # Print the Protocol sections + if (len(ProtocolCName) + len(ProtocolCNameIa32) + len(ProtocolCNameIPF) + len(ProtocolCNameX64) + len(ProtocolCNameEBC)) > 0: +## ProtocolsSection = "\n" + "#"*80 + "\n#\n" +## ProtocolsSection += "# Protocol C Name Section - list of Protocol and Protocol Notify C Names\n" +## ProtocolsSection += "# that this module uses or produces.\n" +## ProtocolsSection += "#\n" + "#"*80 + "\n\n" + + ProtocolsSection = "\n" + if (len(ProtocolCName) > 0): + ProtocolsSection += "[Protocols]\n" + for Guid in ProtocolCName[:]: + ProtocolsSection += Guid + "\n" + ProtocolsSection += "\n" + + if (len(ProtocolCNameIa32) > 0): + ProtocolsSection += "[Protocols.IA32]\n" + for Guid in ProtocolCNameIa32[:]: + ProtocolsSection += Guid + "\n" + ProtocolsSection += "\n" + + if (len(ProtocolCNameX64) > 0): + ProtocolsSection += "[Protocols.X64]\n" + for Guid in ProtocolCNameX64[:]: + ProtocolsSection += Guid + "\n" + ProtocolsSection += "\n" + + if (len(ProtocolCNameIPF) > 0): + ProtocolsSection += "[Protocols.IPF]\n" + for Guid in ProtocolCNameIPF[:]: + ProtocolsSection += Guid + "\n" + ProtocolsSection += "\n" + + if (len(ProtocolCNameEBC) > 0): + ProtocolsSection += "[Protocols.EBC]\n" + for Guid in ProtocolCNameEBC[:]: + ProtocolsSection += Guid + "\n" + ProtocolsSection += "\n" + + Output.append(ProtocolsSection) + if (options.debug): + print ProtocolsSection + + # Print the PPI sections + if (len(PpiCName) + len(PpiCNameIa32) + len(PpiCNameIPF) + len(PpiCNameX64) + len(PpiCNameEBC)) > 0: +## PpiSection = "\n" + "#"*80 + "\n#\n" +## PpiSection += "# PPI C Name Section - list of PPI and PPI Notify C Names that this module\n" +## PpiSection += "# uses or produces.\n" +## PpiSection += "#\n" + "#"*80 + "\n\n" + + PpiSection = "\n" + if (len(PpiCName) > 0): + PpiSection += "[Ppis]\n" + for Guid in PpiCName[:]: + PpiSection += Guid + "\n" + PpiSection += "\n" + + if (len(PpiCNameIa32) > 0): + PpiSection += "[Ppis.IA32]\n" + for Guid in PpiCNameIa32[:]: + PpiSection += Guid + "\n" + PpiSection += "\n" + + if (len(PpiCNameX64) > 0): + PpiSection += "[Ppis.X64]\n" + for Guid in PpiCNameX64[:]: + PpiSection += Guid + "\n" + PpiSection += "\n" + + if (len(PpiCNameIPF) > 0): + PpiSection += "[Ppis.IPF]\n" + for Guid in PpiCNameIPF[:]: + PpiSection += Guid + "\n" + PpiSection += "\n" + + if (len(PpiCNameEBC) > 0): + PpiSection += "[Ppis.EBC]\n" + for Guid in PpiCNameEBC[:]: + PpiSection += Guid + "\n" + PpiSection += "\n" + + Output.append(PpiSection) + if (options.debug): + print PpiSection + + # Print the PCD sections + if ((len(PcdFF)+len(PcdFFIa32)+len(PcdFFX64)+len(PcdFFIpf)+len(PcdFFEbc)) > 0): +## FeatureFlagSection = "\n" + "#"*80 + "\n#\n" +## FeatureFlagSection += "# Pcd FEATURE_FLAG - list of PCDs that this module is coded for.\n" +## FeatureFlagSection += "#\n" + "#"*80 + "\n\n" + + FeatureFlagSection = "\n" + if (len(PcdFF) > 0): + FeatureFlagSection += "[FeaturePcd.common]\n" + for Entry in PcdFF[:]: + FeatureFlagSection += " " + Entry + "\n" + FeatureFlagSection += "\n" + if (len(PcdFFIa32) > 0): + FeatureFlagSection += "[FeaturePcd.IA32]\n" + for Entry in PcdFFIa32[:]: + FeatureFlagSection += " " + Entry + "\n" + FeatureFlagSection += "\n" + if (len(PcdFFX64) > 0): + FeatureFlagSection += "[FeaturePcd.X64]\n" + for Entry in PcdFFX64[:]: + FeatureFlagSection += " " + Entry + "\n" + FeatureFlagSection += "\n" + if (len(PcdFFIpf) > 0): + FeatureFlagSection += "[PcdsFeatureFlag.IPF]\n" + for Entry in PcdFFIpf[:]: + FeatureFlagSection += " " + Entry + "\n" + FeatureFlagSection += "\n" + if (len(PcdFFEbc) > 0): + FeatureFlagSection += "[FeaturePcd.EBC]\n" + for Entry in PcdFFEbc[:]: + FeatureFlagSection += " " + Entry + "\n" + FeatureFlagSection += "\n" + + Output.append(FeatureFlagSection) + if (options.debug): + print FeatureFlagSection + + if ((len(PcdFAB)+len(PcdFABIa32)+len(PcdFABX64)+len(PcdFABIpf)+len(PcdFABEbc)) > 0): +## FixedAtBuildSection = "\n" + "#"*80 + "\n#\n" +## FixedAtBuildSection += "# Pcd FIXED_AT_BUILD - list of PCDs that this module is coded for.\n" +## FixedAtBuildSection += "#\n" + "#"*80 + "\n\n" + + FixedAtBuildSection = "\n" + if (len(PcdFAB) > 0): + FixedAtBuildSection += "[FixedPcd.common]\n" + for Entry in PcdFAB[:]: + FixedAtBuildSection += " " + Entry + "\n" + FixedAtBuildSection += "\n" + if (len(PcdFABIa32) > 0): + FixedAtBuildSection += "[FixedPcd.IA32]\n" + for Entry in PcdFABIa32[:]: + FixedAtBuildSection += " " + Entry + "\n" + FixedAtBuildSection += "\n" + if (len(PcdFABX64) > 0): + FixedAtBuildSection += "[FixedPcd.X64]\n" + for Entry in PcdFABX64[:]: + FixedAtBuildSection += " " + Entry + "\n" + FixedAtBuildSection += "\n" + if (len(PcdFABIpf) > 0): + FixedAtBuildSection += "[FixedPcd.IPF]\n" + for Entry in PcdFABIpf[:]: + FixedAtBuildSection += " " + Entry + "\n" + FixedAtBuildSection += "\n" + if (len(PcdFABEbc) > 0): + FixedAtBuildSection += "[FixedPcd.EBC]\n" + for Entry in PcdFABEbc[:]: + FixedAtBuildSection += " " + Entry + "\n" + FixedAtBuildSection += "\n" + + Output.append(FixedAtBuildSection) + if (options.debug): + print FixedAtBuildSection + + if ((len(PcdPIM)+len(PcdPIMIa32)+len(PcdPIMX64)+len(PcdPIMIpf)+len(PcdPIMEbc)) > 0): +## PatchableInModuleSection = "\n" + "#"*80 + "\n#\n" +## PatchableInModuleSection += "# Pcd PATCHABLE_IN_MODULE - list of PCDs that this module is coded for.\n" +## PatchableInModuleSection += "#\n" + "#"*80 + "\n\n" + + PatchableInModuleSection = "\n" + if (len(PcdPIM) > 0): + PatchableInModuleSection += "[PatchPcd.common]\n" + for Entry in PcdPIM[:]: + PatchableInModuleSection += " " + Entry + "\n" + PatchableInModuleSection += "\n" + if (len(PcdPIMIa32) > 0): + PatchableInModuleSection += "[PatchPcd.IA32]\n" + for Entry in PcdPIMIa32[:]: + PatchableInModuleSection += " " + Entry + "\n" + PatchableInModuleSection += "\n" + if (len(PcdPIMX64) > 0): + PatchableInModuleSection += "[PatchPcd.X64]\n" + for Entry in PcdPIMX64[:]: + PatchableInModuleSection += " " + Entry + "\n" + PatchableInModuleSection += "\n" + if (len(PcdPIMIpf) > 0): + PatchableInModuleSection += "[PatchPcd.IPF]\n" + for Entry in PcdPIMIpf[:]: + PatchableInModuleSection += " " + Entry + "\n" + PatchableInModuleSection += "\n" + if (len(PcdPIMEbc) > 0): + PatchableInModuleSection += "[PatchPcd.EBC]\n" + for Entry in PcdPIMEbc[:]: + PatchableInModuleSection += " " + Entry + "\n" + PatchableInModuleSection += "\n" + + Output.append(PatchableInModuleSection) + if (options.debug): + print PatchableInModuleSection + + if ((len(PcdDYE)+len(PcdDYEIa32)+len(PcdDYEX64)+len(PcdDYEIpf)+len(PcdDYEEbc)) > 0): +## DynamicExSection = "\n" + "#"*80 + "\n#\n" +## DynamicExSection += "# Pcd DYNAMIC_EX - list of PCDs that this module is coded for.\n" +## DynamicExSection += "#\n" + "#"*80 + "\n\n" + + DynamicExSection = "\n" + if (len(PcdDYE) > 0): + DynamicExSection += "[PcdEx.common]\n" + for Entry in PcdDYE[:]: + DynamicExSection += " " + Entry + "\n" + DynamicExSection += "\n" + if (len(PcdDYEIa32) > 0): + DynamicExSection += "[PcdEx.IA32]\n" + for Entry in PcdDYEIa32[:]: + DynamicExSection += " " + Entry + "\n" + DynamicExSection += "\n" + if (len(PcdDYEX64) > 0): + DynamicExSection += "[PcdEx.X64]\n" + for Entry in PcdDYEX64[:]: + DynamicExSection += " " + Entry + "\n" + DynamicExSection += "\n" + if (len(PcdDYEIpf) > 0): + DynamicExSection += "[PcdEx.IPF]\n" + for Entry in PcdDYEIpf[:]: + DynamicExSection += " " + Entry + "\n" + DynamicExSection += "\n" + if (len(PcdDYEEbc) > 0): + DynamicExSection += "[PcdEx.EBC]\n" + for Entry in PcdDYEEbc[:]: + DynamicExSection += " " + Entry + "\n" + DynamicExSection += "\n" + + Output.append(DynamicExSection) + if (options.debug): + print DynamicExSection + + if ((len(PcdDY)+len(PcdDYIa32)+len(PcdDYX64)+len(PcdDYIpf)+len(PcdDYEbc)) > 0): +## DynamicSection = "\n" + "#"*80 + "\n#\n" +## DynamicSection += "# Pcd DYNAMIC - list of PCDs that this module is coded for.\n" +## DynamicSection += "#\n" + "#"*80 + "\n\n" + + DynamicSection = "\n" + if (len(PcdDY) > 0): + DynamicSection += "[Pcd.common]\n" + for Entry in PcdDY[:]: + DynamicSection += " " + Entry + "\n" + DynamicSection += "\n" + if (len(PcdDYIa32) > 0): + DynamicSection += "[Pcd.IA32]\n" + for Entry in PcdDYIa32[:]: + DynamicSection += " " + Entry + "\n" + DynamicSection += "\n" + if (len(PcdDYX64) > 0): + DynamicSection += "[Pcd.X64]\n" + for Entry in PcdDYX64[:]: + DynamicSection += " " + Entry + "\n" + DynamicSection += "\n" + if (len(PcdDYIpf) > 0): + DynamicSection += "[Pcd.IPF]\n" + for Entry in PcdDYIpf[:]: + DynamicSection += " " + Entry + "\n" + DynamicSection += "\n" + if (len(PcdDYEbc) > 0): + DynamicSection += "[Pcd.EBC]\n" + for Entry in PcdDYEbc[:]: + DynamicSection += " " + Entry + "\n" + DynamicSection += "\n" + + Output.append(DynamicSection) + if (options.debug): + print DynamicSection + + if ((len(Depex) + len(DepexIa32) + len(DepexX64) + len(DepexIpf) + len(DepexEbc)) > 0): + """ We do this if and only if we have Package Dependencies """ +## Dpx = "\n" + "#"*80 + "\n#\n" +## Dpx += "# Dependency Expression Section - list of Dependency expressions that are required for\n" +## Dpx += "# this module.\n" +## Dpx += "#\n" + "#"*80 + "\n\n" + Dpx = "\n" + if (len(Depex) > 0): + Dpx += "[Depex]\n" + for lc in Depex[:]: + Dpx += " " + lc + "\n" + Dpx += "\n" + + if (len(DepexIa32) > 0): + Dpx += "[Depex.IA32]\n" + for lc in DepexIa32[:]: + Dpx += " " + lc + "\n" + Dpx += "\n" + + if (len(DepexX64) > 0): + Dpx += "[Depex.X64]\n" + for lc in DepexX64[:]: + Dpx += " " + lc + "\n" + Dpx += "\n" + + if (len(DepexIpf) > 0): + Dpx += "[Depex.IPF]\n" + for lc in DepexIpf[:]: + Dpx += " " + lc + "\n" + Dpx += "\n" + + if (len(DepexEbc) > 0): + Dpx += "[Depex.EBC]\n" + for lc in DepexEbc[:]: + Dpx += " " + lc + "\n" + Dpx += "\n" + + Output.append(Dpx) + if (options.debug): + print Dpx + + if (len(MBOlines) > 0): + BuildSection = "" +## BuildSection = "\n" + "#"*80 + "\n#\n" +## BuildSection += "# Build Options - list of custom build options for this module.\n" +## BuildSection += "#\n" + "#"*80 + "\n\n" + BuildSection += "\n[BuildOptions]\n" + for mbo in MBOlines: + tool, targs = mbo.split("=",2) + BuildSection += " %-40s = %s\n" % (tool.strip(), targs.strip()) + + Output.append(BuildSection) + if (options.debug): + print BuildSection + + + if (len(UEList) > 0): + UserExtensionSection = "" + for UE in UEList[:]: + UserExtensionSection += "[UserExtensions." + UE[0] + '."' + UE[1] + '"]\n' + if (len(UE[2]) > 0): + UserExtensionSection += '"' + UE[2] + '"\n' + else: + UserExtensionSection += "\n" + + Output.append(UserExtensionSection) + if (options.debug): + print UserExtensionSection + + print "write file", outputFile + if (options.autowrite): + fo = open(outputFile, "w") + for Section in Output[:]: + fo.writelines(Section) + if (options.verbose > 1): + print Section + fo.close() + elif (options.outfile): + fo = open(outputFile, "w") + for Section in Output[:]: + fo.writelines(Section) + fo.close() + else: + for Section in Output[:]: + print Section + + +if __name__ == '__main__': + + global options + global args + options,args = myOptionParser() + + main() + sys.exit(0) + diff --git a/BaseTools/Source/Python/MigrationMsa2Inf/__init__.py b/BaseTools/Source/Python/MigrationMsa2Inf/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/BaseTools/Source/Python/MkBOM/__init__.py b/BaseTools/Source/Python/MkBOM/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/BaseTools/Source/Python/PackagingTool/DependencyRules.py b/BaseTools/Source/Python/PackagingTool/DependencyRules.py new file mode 100644 index 0000000000..402694054e --- /dev/null +++ b/BaseTools/Source/Python/PackagingTool/DependencyRules.py @@ -0,0 +1,185 @@ +## @file +# This file is for installed package information database operations +# +# Copyright (c) 2007 ~ 2008, 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 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 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 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 satified 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 satified 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 satified 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 satified by current workspace. + # + # @param ModuleObj: + # @param DpObj: + # + def CheckDpDepexForRemove(self, DpGuid, DpVersion, ReturnCode = DEPEX_CHECK_SUCCESS): + + # Get mod list that is dependent on pkg installed from this DP. + ModList = self.IpiDb.GetDpDependentModuleList(DpGuid, DpVersion) + + if len(ModList) > 0: + return False + + return True +## +# +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +# +if __name__ == '__main__': + EdkLogger.Initialize() + EdkLogger.SetLevel(EdkLogger.DEBUG_0) + + + \ No newline at end of file diff --git a/BaseTools/Source/Python/PackagingTool/InstallPkg.py b/BaseTools/Source/Python/PackagingTool/InstallPkg.py new file mode 100644 index 0000000000..963a654ea1 --- /dev/null +++ b/BaseTools/Source/Python/PackagingTool/InstallPkg.py @@ -0,0 +1,309 @@ +## @file +# Install distribution package. +# +# Copyright (c) 2007, 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 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/ 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 [-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 dev@buildtools.tianocore.org for help, attaching following call stack trace!)\n", + RaiseError=False + ) + EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc()) + ReturnCode = CODE_ERROR + finally: + EdkLogger.quiet("Removing temp files ... ") + if DistFile: + DistFile.Close() + if ContentZipFile: + ContentZipFile.Close() + if UnpackDir: + shutil.rmtree(UnpackDir) + + EdkLogger.quiet("DONE") + Progressor.Abort() + +if __name__ == '__main__': + sys.exit(Main()) diff --git a/BaseTools/Source/Python/PackagingTool/IpiDb.py b/BaseTools/Source/Python/PackagingTool/IpiDb.py new file mode 100644 index 0000000000..8661edbca4 --- /dev/null +++ b/BaseTools/Source/Python/PackagingTool/IpiDb.py @@ -0,0 +1,629 @@ +## @file +# This file is for installed package information database operations +# +# Copyright (c) 2007 ~ 2008, 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 accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# + +## +# Import Modules +# +import sqlite3 +import os +import time +import Common.EdkLogger as EdkLogger + +from CommonDataClass import DistributionPackageClass + +## IpiDb +# +# This class represents the installed package information databse +# Add/Remove/Get installed distribution package information here. +# +# +# @param object: Inherited from object class +# @param DbPath: A string for the path of the database +# +# @var Conn: Connection of the database +# @var Cur: Cursor of the connection +# +class IpiDatabase(object): + def __init__(self, DbPath): + Dir = os.path.dirname(DbPath) + if not os.path.isdir(Dir): + os.mkdir(Dir) + self.Conn = sqlite3.connect(DbPath, isolation_level = 'DEFERRED') + self.Conn.execute("PRAGMA page_size=4096") + self.Conn.execute("PRAGMA synchronous=OFF") + self.Cur = self.Conn.cursor() + self.DpTable = 'DpInfo' + self.PkgTable = 'PkgInfo' + self.ModInPkgTable = 'ModInPkgInfo' + self.StandaloneModTable = 'StandaloneModInfo' + self.ModDepexTable = 'ModDepexInfo' + self.DpFileListTable = 'DpFileListInfo' + + ## Initialize build database + # + # + def InitDatabase(self): + EdkLogger.verbose("\nInitialize IPI database started ...") + + # + # Create new table + # + SqlCommand = """create table IF NOT EXISTS %s (DpGuid TEXT NOT NULL, + DpVersion TEXT NOT NULL, + InstallTime REAL NOT NULL, + PkgFileName TEXT, + PRIMARY KEY (DpGuid, DpVersion) + )""" % self.DpTable + self.Cur.execute(SqlCommand) + + SqlCommand = """create table IF NOT EXISTS %s (FilePath TEXT NOT NULL, + DpGuid TEXT, + DpVersion TEXT, + PRIMARY KEY (FilePath) + )""" % self.DpFileListTable + self.Cur.execute(SqlCommand) + + SqlCommand = """create table IF NOT EXISTS %s (PackageGuid TEXT NOT NULL, + PackageVersion TEXT NOT NULL, + InstallTime REAL NOT NULL, + DpGuid TEXT, + DpVersion TEXT, + InstallPath TEXT NOT NULL, + PRIMARY KEY (PackageGuid, PackageVersion, InstallPath) + )""" % self.PkgTable + self.Cur.execute(SqlCommand) + + SqlCommand = """create table IF NOT EXISTS %s (ModuleGuid TEXT NOT NULL, + ModuleVersion TEXT NOT NULL, + InstallTime REAL NOT NULL, + PackageGuid TEXT, + PackageVersion TEXT, + InstallPath TEXT NOT NULL, + PRIMARY KEY (ModuleGuid, ModuleVersion, InstallPath) + )""" % self.ModInPkgTable + self.Cur.execute(SqlCommand) + + SqlCommand = """create table IF NOT EXISTS %s (ModuleGuid TEXT NOT NULL, + ModuleVersion TEXT NOT NULL, + InstallTime REAL NOT NULL, + DpGuid TEXT, + DpVersion TEXT, + InstallPath TEXT NOT NULL, + PRIMARY KEY (ModuleGuid, ModuleVersion, InstallPath) + )""" % self.StandaloneModTable + self.Cur.execute(SqlCommand) + + SqlCommand = """create table IF NOT EXISTS %s (ModuleGuid TEXT NOT NULL, + ModuleVersion TEXT NOT NULL, + InstallPath TEXT NOT NULL, + DepexGuid TEXT, + DepexVersion TEXT + )""" % self.ModDepexTable + self.Cur.execute(SqlCommand) + + self.Conn.commit() + + EdkLogger.verbose("Initialize IPI database ... DONE!") + + ## Add a distribution install information from DpObj + # + # @param DpObj: + # + def AddDPObject(self, DpObj): + + for PkgKey in DpObj.PackageSurfaceArea.keys(): + PkgGuid = PkgKey[0] + PkgVersion = PkgKey[1] + PkgInstallPath = PkgKey[2] + self.AddPackage(PkgGuid, PkgVersion, DpObj.Header.Guid, DpObj.Header.Version, PkgInstallPath) + PkgObj = DpObj.PackageSurfaceArea[PkgKey] + for ModKey in PkgObj.Modules.keys(): + ModGuid = ModKey[0] + ModVersion = ModKey[1] + ModInstallPath = ModKey[2] + self.AddModuleInPackage(ModGuid, ModVersion, PkgGuid, PkgVersion, ModInstallPath) + ModObj = PkgObj.Modules[ModKey] + for Dep in ModObj.PackageDependencies: + DepexGuid = Dep.PackageGuid + DepexVersion = Dep.PackageVersion + self.AddModuleDepex(ModGuid, ModVersion, ModInstallPath, DepexGuid, DepexVersion) + for FilePath in PkgObj.FileList: + self.AddDpFilePathList(DpObj.Header.Guid, DpObj.Header.Version, FilePath) + + for ModKey in DpObj.ModuleSurfaceArea.keys(): + ModGuid = ModKey[0] + ModVersion = ModKey[1] + ModInstallPath = ModKey[2] + self.AddStandaloneModule(ModGuid, ModVersion, DpObj.Header.Guid, DpObj.Header.Version, ModInstallPath) + ModObj = DpObj.ModuleSurfaceArea[ModKey] + for Dep in ModObj.PackageDependencies: + DepexGuid = Dep.PackageGuid + DepexVersion = Dep.PackageVersion + self.AddModuleDepex(ModGuid, ModVersion, ModInstallPath, DepexGuid, DepexVersion) + for FilePath in ModObj.FileList: + self.AddDpFilePathList(DpObj.Header.Guid, DpObj.Header.Version, FilePath) + + self.AddDp(DpObj.Header.Guid, DpObj.Header.Version, DpObj.Header.FileName) + ## Add a distribution install information + # + # @param Guid: + # @param Version: + # @param PkgFileName: + # + def AddDp(self, Guid, Version, PkgFileName = None): + + if Version == None or len(Version.strip()) == 0: + Version = 'N/A' + + # + # Add newly installed DP information to DB. + # + if PkgFileName == None or len(PkgFileName.strip()) == 0: + PkgFileName = 'N/A' + (Guid, Version, PkgFileName) = (Guid, Version, PkgFileName) + CurrentTime = time.time() + SqlCommand = """insert into %s values('%s', '%s', %s, '%s')""" % (self.DpTable, Guid, Version, CurrentTime, PkgFileName) + self.Cur.execute(SqlCommand) + self.Conn.commit() + + ## Add a file list from DP + # + # @param DpGuid: + # @param DpVersion: + # @param Path + # + def AddDpFilePathList(self, DpGuid, DpVersion, Path): + + SqlCommand = """insert into %s values('%s', '%s', '%s')""" % (self.DpFileListTable, Path, DpGuid, DpVersion) + self.Cur.execute(SqlCommand) + self.Conn.commit() + + ## Add a package install information + # + # @param Guid: + # @param Version: + # @param DpGuid: + # @param DpVersion: + # @param Path + # + def AddPackage(self, Guid, Version, DpGuid = None, DpVersion = None, Path = ''): + + if Version == None or len(Version.strip()) == 0: + Version = 'N/A' + + if DpGuid == None or len(DpGuid.strip()) == 0: + DpGuid = 'N/A' + + if DpVersion == None or len(DpVersion.strip()) == 0: + DpVersion = 'N/A' + + # + # Add newly installed package information to DB. + # + + CurrentTime = time.time() + SqlCommand = """insert into %s values('%s', '%s', %s, '%s', '%s', '%s')""" % (self.PkgTable, Guid, Version, CurrentTime, DpGuid, DpVersion, Path) + self.Cur.execute(SqlCommand) + self.Conn.commit() + + ## Add a module that from a package install information + # + # @param Guid: + # @param Version: + # @param PkgFileName: + # + def AddModuleInPackage(self, Guid, Version, PkgGuid = None, PkgVersion = None, Path = ''): + + if Version == None or len(Version.strip()) == 0: + Version = 'N/A' + + if PkgGuid == None or len(PkgGuid.strip()) == 0: + PkgGuid = 'N/A' + + if PkgVersion == None or len(PkgVersion.strip()) == 0: + PkgVersion = 'N/A' + + # + # Add module from package information to DB. + # + CurrentTime = time.time() + SqlCommand = """insert into %s values('%s', '%s', %s, '%s', '%s', '%s')""" % (self.ModInPkgTable, Guid, Version, CurrentTime, PkgGuid, PkgVersion, Path) + self.Cur.execute(SqlCommand) + self.Conn.commit() + + ## Add a module that is standalone install information + # + # @param Guid: + # @param Version: + # @param PkgFileName: + # + def AddStandaloneModule(self, Guid, Version, DpGuid = None, DpVersion = None, Path = ''): + + if Version == None or len(Version.strip()) == 0: + Version = 'N/A' + + if DpGuid == None or len(DpGuid.strip()) == 0: + DpGuid = 'N/A' + + if DpVersion == None or len(DpVersion.strip()) == 0: + DpVersion = 'N/A' + + # + # Add module standalone information to DB. + # + CurrentTime = time.time() + SqlCommand = """insert into %s values('%s', '%s', %s, '%s', '%s', '%s')""" % (self.StandaloneModTable, Guid, Version, CurrentTime, DpGuid, DpVersion, Path) + self.Cur.execute(SqlCommand) + self.Conn.commit() + + ## Add a module depex + # + # @param Guid: + # @param Version: + # @param DepexGuid: + # @param DepexVersion: + # + def AddModuleDepex(self, Guid, Version, Path, DepexGuid = None, DepexVersion = None): + + if DepexGuid == None or len(DepexGuid.strip()) == 0: + DepexGuid = 'N/A' + + if DepexVersion == None or len(DepexVersion.strip()) == 0: + DepexVersion = 'N/A' + + # + # Add module depex information to DB. + # + + SqlCommand = """insert into %s values('%s', '%s', '%s', '%s', '%s')""" % (self.ModDepexTable, Guid, Version, Path, DepexGuid, DepexVersion) + self.Cur.execute(SqlCommand) + self.Conn.commit() + + ## Remove a distribution install information, if no version specified, remove all DPs with this Guid. + # + # @param DpObj: + # + def RemoveDpObj(self, DpGuid, DpVersion): + + PkgList = self.GetPackageListFromDp(DpGuid, DpVersion) + + # delete from ModDepex the standalone module's dependency + SqlCommand = """delete from ModDepexInfo where ModDepexInfo.ModuleGuid in + (select ModuleGuid from StandaloneModInfo as B where B.DpGuid = '%s' and B.DpVersion = '%s') + and ModDepexInfo.ModuleVersion in + (select ModuleVersion from StandaloneModInfo as B where B.DpGuid = '%s' and B.DpVersion = '%s') + and ModDepexInfo.InstallPath in + (select InstallPath from StandaloneModInfo as B where B.DpGuid = '%s' and B.DpVersion = '%s') """ \ + %(DpGuid, DpVersion, DpGuid, DpVersion, DpGuid, DpVersion) + +# SqlCommand = """delete from %s where %s.DpGuid ='%s' and %s.DpVersion = '%s' and +# %s.ModuleGuid = %s.ModuleGuid and %s.ModuleVersion = %s.ModuleVersion and +# %s.InstallPath = %s.InstallPath""" \ +# % (self.ModDepexTable, self.StandaloneModTable, DpGuid, self.StandaloneModTable, DpVersion, self.ModDepexTable, self.StandaloneModTable, self.ModDepexTable, self.StandaloneModTable, self.ModDepexTable, self.StandaloneModTable) +# print SqlCommand + self.Cur.execute(SqlCommand) + + # delete from ModDepex the from pkg module's dependency + for Pkg in PkgList: +# SqlCommand = """delete from %s where %s.PackageGuid ='%s' and %s.PackageVersion = '%s' and +# %s.ModuleGuid = %s.ModuleGuid and %s.ModuleVersion = %s.ModuleVersion and +# %s.InstallPath = %s.InstallPath""" \ +# % (self.ModDepexTable, self.ModInPkgTable, Pkg[0], self.ModInPkgTable, Pkg[1], self.ModDepexTable, self.ModInPkgTable, self.ModDepexTable, self.ModInPkgTable, self.ModDepexTable, self.ModInPkgTable) + SqlCommand = """delete from ModDepexInfo where ModDepexInfo.ModuleGuid in + (select ModuleGuid from ModInPkgInfo where ModInPkgInfo.PackageGuid ='%s' and ModInPkgInfo.PackageVersion = '%s') + and ModDepexInfo.ModuleVersion in + (select ModuleVersion from ModInPkgInfo where ModInPkgInfo.PackageGuid ='%s' and ModInPkgInfo.PackageVersion = '%s') + and ModDepexInfo.InstallPath in + (select InstallPath from ModInPkgInfo where ModInPkgInfo.PackageGuid ='%s' and ModInPkgInfo.PackageVersion = '%s')""" \ + % (Pkg[0], Pkg[1],Pkg[0], Pkg[1],Pkg[0], Pkg[1]) + + self.Cur.execute(SqlCommand) + + # delete the standalone module + SqlCommand = """delete from %s where DpGuid ='%s' and DpVersion = '%s'""" % (self.StandaloneModTable, DpGuid, DpVersion) + self.Cur.execute(SqlCommand) + + # delete the from pkg module + for Pkg in PkgList: + SqlCommand = """delete from %s where %s.PackageGuid ='%s' and %s.PackageVersion = '%s'""" \ + % (self.ModInPkgTable, self.ModInPkgTable, Pkg[0], self.ModInPkgTable, Pkg[1]) + self.Cur.execute(SqlCommand) + + # delete packages + SqlCommand = """delete from %s where DpGuid ='%s' and DpVersion = '%s'""" % (self.PkgTable, DpGuid, DpVersion) + self.Cur.execute(SqlCommand) + + # delete file list from DP + SqlCommand = """delete from %s where DpGuid ='%s' and DpVersion = '%s'""" % (self.DpFileListTable, DpGuid, DpVersion) + self.Cur.execute(SqlCommand) + + # delete DP + SqlCommand = """delete from %s where DpGuid ='%s' and DpVersion = '%s'""" % (self.DpTable, DpGuid, DpVersion) + self.Cur.execute(SqlCommand) + + self.Conn.commit() + + ## Get a list of distribution install information. + # + # @param Guid: + # @param Version: + # + def GetDp(self, Guid, Version): + + if Version == None or len(Version.strip()) == 0: + Version = 'N/A' + EdkLogger.verbose("\nGetting list of DP install information started ...") + (DpGuid, DpVersion) = (Guid, Version) + SqlCommand = """select * from %s where DpGuid ='%s'""" % (self.DpTable, DpGuid) + self.Cur.execute(SqlCommand) + + else: + EdkLogger.verbose("\nGetting DP install information started ...") + (DpGuid, DpVersion) = (Guid, Version) + SqlCommand = """select * from %s where DpGuid ='%s' and DpVersion = '%s'""" % (self.DpTable, DpGuid, DpVersion) + self.Cur.execute(SqlCommand) + + DpList = [] + for DpInfo in self.Cur: + DpGuid = DpInfo[0] + DpVersion = DpInfo[1] + InstallTime = DpInfo[2] + PkgFileName = DpInfo[3] + DpList.append((DpGuid, DpVersion, InstallTime, PkgFileName)) + + EdkLogger.verbose("Getting DP install information ... DONE!") + return DpList + + ## Get a list of distribution install file path information. + # + # @param Guid: + # @param Version: + # + def GetDpFileList(self, Guid, Version): + + (DpGuid, DpVersion) = (Guid, Version) + SqlCommand = """select * from %s where DpGuid ='%s' and DpVersion = '%s'""" % (self.DpFileListTable, DpGuid, DpVersion) + self.Cur.execute(SqlCommand) + + PathList = [] + for Result in self.Cur: + Path = Result[0] + PathList.append(Path) + + return PathList + + ## Get a list of package information. + # + # @param Guid: + # @param Version: + # + def GetPackage(self, Guid, Version, DpGuid = '', DpVersion = ''): + + if DpVersion == '' or DpGuid == '': + + (PackageGuid, PackageVersion) = (Guid, Version) + SqlCommand = """select * from %s where PackageGuid ='%s' and PackageVersion = '%s'""" % (self.PkgTable, PackageGuid, PackageVersion) + self.Cur.execute(SqlCommand) + + elif Version == None or len(Version.strip()) == 0: + + SqlCommand = """select * from %s where PackageGuid ='%s'""" % (self.PkgTable, Guid) + self.Cur.execute(SqlCommand) + else: + (PackageGuid, PackageVersion) = (Guid, Version) + SqlCommand = """select * from %s where PackageGuid ='%s' and PackageVersion = '%s' + and DpGuid = '%s' and DpVersion = '%s'""" % (self.PkgTable, PackageGuid, PackageVersion, DpGuid, DpVersion) + self.Cur.execute(SqlCommand) + + PkgList = [] + for PkgInfo in self.Cur: + PkgGuid = PkgInfo[0] + PkgVersion = PkgInfo[1] + InstallTime = PkgInfo[2] + InstallPath = PkgInfo[5] + PkgList.append((PkgGuid, PkgVersion, InstallTime, DpGuid, DpVersion, InstallPath)) + + return PkgList + + ## Get a list of module in package information. + # + # @param Guid: + # @param Version: + # + def GetModInPackage(self, Guid, Version, PkgGuid = '', PkgVersion = ''): + + if PkgVersion == '' or PkgGuid == '': + + (ModuleGuid, ModuleVersion) = (Guid, Version) + SqlCommand = """select * from %s where ModuleGuid ='%s' and ModuleVersion = '%s'""" % (self.ModInPkgTable, ModuleGuid, ModuleVersion) + self.Cur.execute(SqlCommand) + + else: + (ModuleGuid, ModuleVersion) = (Guid, Version) + SqlCommand = """select * from %s where ModuleGuid ='%s' and ModuleVersion = '%s' and PackageGuid ='%s' and PackageVersion = '%s' + """ % (self.ModInPkgTable, ModuleGuid, ModuleVersion, PkgGuid, PkgVersion) + self.Cur.execute(SqlCommand) + + ModList = [] + for ModInfo in self.Cur: + ModGuid = ModInfo[0] + ModVersion = ModInfo[1] + InstallTime = ModInfo[2] + InstallPath = ModInfo[5] + ModList.append((ModGuid, ModVersion, InstallTime, PkgGuid, PkgVersion, InstallPath)) + + return ModList + + ## Get a list of module standalone. + # + # @param Guid: + # @param Version: + # + def GetStandaloneModule(self, Guid, Version, DpGuid = '', DpVersion = ''): + + if DpGuid == '': + + (ModuleGuid, ModuleVersion) = (Guid, Version) + SqlCommand = """select * from %s where ModuleGuid ='%s' and ModuleVersion = '%s'""" % (self.StandaloneModTable, ModuleGuid, ModuleVersion) + self.Cur.execute(SqlCommand) + + else: + (ModuleGuid, ModuleVersion) = (Guid, Version) + SqlCommand = """select * from %s where ModuleGuid ='%s' and ModuleVersion = '%s' and DpGuid ='%s' and DpVersion = '%s' + """ % (self.StandaloneModTable, ModuleGuid, ModuleVersion, DpGuid, DpVersion) + self.Cur.execute(SqlCommand) + + ModList = [] + for ModInfo in self.Cur: + ModGuid = ModInfo[0] + ModVersion = ModInfo[1] + InstallTime = ModInfo[2] + InstallPath = ModInfo[5] + ModList.append((ModGuid, ModVersion, InstallTime, DpGuid, DpVersion, InstallPath)) + + return ModList + + ## Get a list of module information that comes from DP. + # + # @param DpGuid: + # @param DpVersion: + # + def GetStandaloneModuleInstallPathListFromDp(self, DpGuid, DpVersion): + + PathList = [] + SqlCommand = """select t1.InstallPath from %s t1 where t1.DpGuid ='%s' and t1.DpVersion = '%s' + """ % (self.StandaloneModTable, DpGuid, DpVersion) + self.Cur.execute(SqlCommand) + + for Result in self.Cur: + InstallPath = Result[0] + PathList.append(InstallPath) + + return PathList + + ## Get a list of package information. + # + # @param DpGuid: + # @param DpVersion: + # + def GetPackageListFromDp(self, DpGuid, DpVersion): + + + SqlCommand = """select * from %s where DpGuid ='%s' and DpVersion = '%s' + """ % (self.PkgTable, DpGuid, DpVersion) + self.Cur.execute(SqlCommand) + + PkgList = [] + for PkgInfo in self.Cur: + PkgGuid = PkgInfo[0] + PkgVersion = PkgInfo[1] + InstallPath = PkgInfo[5] + PkgList.append((PkgGuid, PkgVersion, InstallPath)) + + return PkgList + + ## Get a list of modules that depends on package information from a DP. + # + # @param DpGuid: + # @param DpVersion: + # + def GetDpDependentModuleList(self, DpGuid, DpVersion): + + ModList = [] + PkgList = self.GetPackageListFromDp(DpGuid, DpVersion) + if len(PkgList) > 0: + return ModList + + for Pkg in PkgList: + SqlCommand = """select t1.ModuleGuid, t1.ModuleVersion, t1.InstallPath + from %s as t1, %s as t2, where t1.ModuleGuid = t2.ModuleGuid and + t1.ModuleVersion = t2.ModuleVersion and t2.DepexGuid ='%s' and (t2.DepexVersion = '%s' or t2.DepexVersion = 'N/A') and + t1.PackageGuid != '%s' and t1.PackageVersion != '%s' + """ % (self.ModInPkgTable, self.ModDepexTable, Pkg[0], Pkg[1], Pkg[0], Pkg[1]) + self.Cur.execute(SqlCommand) + for ModInfo in self.Cur: + ModGuid = ModInfo[0] + ModVersion = ModInfo[1] + InstallPath = ModInfo[2] + ModList.append((ModGuid, ModVersion, InstallPath)) + + SqlCommand = """select t1.ModuleGuid, t1.ModuleVersion, t1.InstallPath + from %s as t1, %s as t2, where t1.ModuleGuid = t2.ModuleGuid and + t1.ModuleVersion = t2.ModuleVersion and t2.DepexGuid ='%s' and (t2.DepexVersion = '%s' or t2.DepexVersion = 'N/A') and + t1.DpGuid != '%s' and t1.DpVersion != '%s' + """ % (self.StandaloneModTable, self.ModDepexTable, Pkg[0], Pkg[1], DpGuid, DpVersion) + self.Cur.execute(SqlCommand) + for ModInfo in self.Cur: + ModGuid = ModInfo[0] + ModVersion = ModInfo[1] + InstallPath = ModInfo[2] + ModList.append((ModGuid, ModVersion, InstallPath)) + + + return ModList + + ## Get a module depex + # + # @param Guid: + # @param Version: + # @param Path: + # + def GetModuleDepex(self, Guid, Version, Path): + + # + # Get module depex information to DB. + # + + SqlCommand = """select * from %s where ModuleGuid ='%s' and ModuleVersion = '%s' and InstallPath ='%s' + """ % (self.ModDepexTable, Guid, Version, Path) + self.Cur.execute(SqlCommand) + self.Conn.commit() + + DepexList = [] + for DepInfo in self.Cur: + DepexGuid = DepInfo[3] + DepexVersion = DepInfo[4] + DepexList.append((DepexGuid, DepexVersion)) + + return DepexList + + ## Close entire database + # + # Close the connection and cursor + # + def CloseDb(self): + + self.Cur.close() + self.Conn.close() + + ## Convert To Sql String + # + # 1. Replace "'" with "''" in each item of StringList + # + # @param StringList: A list for strings to be converted + # + def __ConvertToSqlString(self, StringList): + return map(lambda s: s.replace("'", "''") , StringList) +## +# +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +# +if __name__ == '__main__': + EdkLogger.Initialize() + EdkLogger.SetLevel(EdkLogger.DEBUG_0) + DATABASE_PATH = "C://MyWork//Conf//.cache//XML.db" + Db = IpiDatabase(DATABASE_PATH) + Db.InitDatabase() + + \ No newline at end of file diff --git a/BaseTools/Source/Python/PackagingTool/MkPkg.py b/BaseTools/Source/Python/PackagingTool/MkPkg.py new file mode 100644 index 0000000000..660f48f05f --- /dev/null +++ b/BaseTools/Source/Python/PackagingTool/MkPkg.py @@ -0,0 +1,294 @@ +## @file +# Install distribution package. +# +# Copyright (c) 2007, 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 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/ 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 -p [-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 dev@buildtools.tianocore.org for help, attaching following call stack trace!)\n", + RaiseError=False + ) + EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc()) + ReturnCode = CODE_ERROR + finally: + Progressor.Abort() + +if __name__ == '__main__': + sys.exit(Main()) + diff --git a/BaseTools/Source/Python/PackagingTool/PackageFile.py b/BaseTools/Source/Python/PackagingTool/PackageFile.py new file mode 100644 index 0000000000..12544927c9 --- /dev/null +++ b/BaseTools/Source/Python/PackagingTool/PackageFile.py @@ -0,0 +1,160 @@ +## @file +# +# PackageFile class represents the zip file of a distribution package. +# +# Copyright (c) 2007, 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 accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# + +## +# Import Modules +# +import os +import sys +import zipfile +import tempfile + +from Common import EdkLogger +from Common.Misc import * +from Common.BuildToolError import * + +class PackageFile: + def __init__(self, FileName, Mode="r"): + self._FileName = FileName + if Mode not in ["r", "w", "a"]: + Mode = "r" + try: + self._ZipFile = zipfile.ZipFile(FileName, Mode, zipfile.ZIP_DEFLATED) + self._Files = {} + for F in self._ZipFile.namelist(): + self._Files[os.path.normpath(F)] = F + except BaseException, X: + EdkLogger.error("PackagingTool", FILE_OPEN_FAILURE, + ExtraData="%s (%s)" % (FileName, str(X))) + + BadFile = self._ZipFile.testzip() + if BadFile != None: + EdkLogger.error("PackagingTool", FILE_CHECKSUM_FAILURE, + ExtraData="[%s] in %s" % (BadFile, FileName)) + + def __str__(self): + return self._FileName + + def Unpack(self, To): + for F in self._ZipFile.namelist(): + ToFile = os.path.normpath(os.path.join(To, F)) + print F, "->", ToFile + self.Extract(F, ToFile) + + def UnpackFile(self, File, ToFile): + File = File.replace('\\', '/') + if File in self._ZipFile.namelist(): + print File, "->", ToFile + self.Extract(File, ToFile) + + return ToFile + + return '' + + def Extract(self, Which, To): + Which = os.path.normpath(Which) + if Which not in self._Files: + EdkLogger.error("PackagingTool", FILE_NOT_FOUND, + ExtraData="[%s] in %s" % (Which, self._FileName)) + try: + FileContent = self._ZipFile.read(self._Files[Which]) + except BaseException, X: + EdkLogger.error("PackagingTool", FILE_DECOMPRESS_FAILURE, + ExtraData="[%s] in %s (%s)" % (Which, self._FileName, str(X))) + try: + CreateDirectory(os.path.dirname(To)) + ToFile = open(To, "wb") + except BaseException, X: + EdkLogger.error("PackagingTool", FILE_OPEN_FAILURE, + ExtraData="%s (%s)" % (To, str(X))) + + try: + ToFile.write(FileContent) + ToFile.close() + except BaseException, X: + EdkLogger.error("PackagingTool", FILE_WRITE_FAILURE, + ExtraData="%s (%s)" % (To, str(X))) + + def Remove(self, Files): + TmpDir = os.path.join(tempfile.gettempdir(), ".packaging") + if os.path.exists(TmpDir): + RemoveDirectory(TmpDir, True) + + os.mkdir(TmpDir) + self.Unpack(TmpDir) + for F in Files: + F = os.path.normpath(F) + if F not in self._Files: + EdkLogger.error("PackagingTool", FILE_NOT_FOUND, + ExtraData="%s is not in %s!" % (F, self._FileName)) + #os.remove(os.path.join(TmpDir, F)) # no need to really remove file + self._Files.pop(F) + self._ZipFile.close() + + self._ZipFile = zipfile.ZipFile(self._FileName, "w", zipfile.ZIP_DEFLATED) + Cwd = os.getcwd() + os.chdir(TmpDir) + self.PackFiles(self._Files) + os.chdir(Cwd) + RemoveDirectory(TmpDir, True) + + def Pack(self, Top): + if not os.path.isdir(Top): + EdkLogger.error("PackagingTool", FILE_UNKNOWN_ERROR, "%s is not a directory!" %Top) + + FilesToPack = [] + ParentDir = os.path.dirname(Top) + BaseDir = os.path.basename(Top) + Cwd = os.getcwd() + os.chdir(ParentDir) + for Root, Dirs, Files in os.walk(BaseDir): + if 'CVS' in Dirs: + Dirs.remove('CVS') + if '.svn' in Dirs: + Dirs.remove('.svn') + for F in Files: + FilesToPack.append(os.path.join(Root, F)) + self.PackFiles(FilesToPack) + os.chdir(Cwd) + + def PackFiles(self, Files): + for F in Files: + try: + print "packing ...", F + self._ZipFile.write(F) + except BaseException, X: + EdkLogger.error("PackagingTool", FILE_COMPRESS_FAILURE, + ExtraData="%s (%s)" % (F, str(X))) + + def PackFile(self, File, ArcName=None): + try: + print "packing ...", File + self._ZipFile.write(File, ArcName) + except BaseException, X: + EdkLogger.error("PackagingTool", FILE_COMPRESS_FAILURE, + ExtraData="%s (%s)" % (File, str(X))) + + def PackData(self, Data, ArcName): + try: + self._ZipFile.writestr(ArcName, Data) + except BaseException, X: + EdkLogger.error("PackagingTool", FILE_COMPRESS_FAILURE, + ExtraData="%s (%s)" % (ArcName, str(X))) + + def Close(self): + self._ZipFile.close() + +if __name__ == '__main__': + pass + diff --git a/BaseTools/Source/Python/PackagingTool/RmPkg.py b/BaseTools/Source/Python/PackagingTool/RmPkg.py new file mode 100644 index 0000000000..e7eedd0776 --- /dev/null +++ b/BaseTools/Source/Python/PackagingTool/RmPkg.py @@ -0,0 +1,218 @@ +## @file +# Install distribution package. +# +# Copyright (c) 2007, 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 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/ 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 -n [-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 dev@buildtools.tianocore.org for help, attaching following call stack trace!)\n", + RaiseError=False + ) + EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc()) + ReturnCode = CODE_ERROR + finally: + Progressor.Abort() + +if __name__ == '__main__': + sys.exit(Main()) diff --git a/BaseTools/Source/Python/Table/Table.py b/BaseTools/Source/Python/Table/Table.py new file mode 100644 index 0000000000..9a9657a4b3 --- /dev/null +++ b/BaseTools/Source/Python/Table/Table.py @@ -0,0 +1,120 @@ +## @file +# This file is used to create/update/query/erase a common table +# +# Copyright (c) 2008, 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 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 Common.EdkLogger as EdkLogger + +## TableFile +# +# This class defined a common table +# +# @param object: Inherited from object class +# +# @param Cursor: Cursor of the database +# @param TableName: Name of the table +# +class Table(object): + def __init__(self, Cursor): + self.Cur = Cursor + self.Table = '' + self.ID = 0 + + ## Create table + # + # Create a table + # + def Create(self, SqlCommand): + self.Cur.execute(SqlCommand) + self.ID = 0 + EdkLogger.verbose(SqlCommand + " ... DONE!") + + ## Insert table + # + # Insert a record into a table + # + def Insert(self, SqlCommand): + self.Exec(SqlCommand) + + ## Query table + # + # Query all records of the table + # + def Query(self): + EdkLogger.verbose("\nQuery tabel %s started ..." % self.Table) + SqlCommand = """select * from %s""" % self.Table + self.Cur.execute(SqlCommand) + for Rs in self.Cur: + EdkLogger.verbose(str(Rs)) + + TotalCount = self.GetCount() + EdkLogger.verbose("*** Total %s records in table %s ***" % (TotalCount, self.Table) ) + EdkLogger.verbose("Query tabel %s DONE!" % self.Table) + + ## Drop a table + # + # Drop the table + # + def Drop(self): + SqlCommand = """drop table IF EXISTS %s""" % self.Table + self.Cur.execute(SqlCommand) + EdkLogger.verbose("Drop tabel %s ... DONE!" % self.Table) + + ## Get count + # + # Get a count of all records of the table + # + # @retval Count: Total count of all records + # + def GetCount(self): + SqlCommand = """select count(ID) from %s""" % self.Table + self.Cur.execute(SqlCommand) + for Item in self.Cur: + return Item[0] + + ## Generate ID + # + # Generate an ID if input ID is -1 + # + # @param ID: Input ID + # + # @retval ID: New generated ID + # + def GenerateID(self, ID): + if ID == -1: + self.ID = self.ID + 1 + + return self.ID + + ## Init the ID of the table + # + # Init the ID of the table + # + def InitID(self): + self.ID = self.GetCount() + + ## Exec + # + # Exec Sql Command, return result + # + # @param SqlCommand: The SqlCommand to be executed + # + # @retval RecordSet: The result after executed + # + def Exec(self, SqlCommand): + EdkLogger.debug(4, "SqlCommand: %s" % SqlCommand) + self.Cur.execute(SqlCommand) + RecordSet = self.Cur.fetchall() + EdkLogger.debug(4, "RecordSet: %s" % RecordSet) + return RecordSet diff --git a/BaseTools/Source/Python/Table/TableDataModel.py b/BaseTools/Source/Python/Table/TableDataModel.py new file mode 100644 index 0000000000..1e5fe47af1 --- /dev/null +++ b/BaseTools/Source/Python/Table/TableDataModel.py @@ -0,0 +1,95 @@ +## @file +# This file is used to create/update/query/erase table for data models +# +# Copyright (c) 2008, 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 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 Common.EdkLogger as EdkLogger +import CommonDataClass.DataClass as DataClass +from Table import Table +from Common.String import ConvertToSqlString + +## TableDataModel +# +# This class defined a table used for data model +# +# @param object: Inherited from object class +# +# +class TableDataModel(Table): + def __init__(self, Cursor): + Table.__init__(self, Cursor) + self.Table = 'DataModel' + + ## Create table + # + # Create table DataModel + # + # @param ID: ID of a ModelType + # @param CrossIndex: CrossIndex of a ModelType + # @param Name: Name of a ModelType + # @param Description: Description of a ModelType + # + def Create(self): + SqlCommand = """create table IF NOT EXISTS %s (ID INTEGER PRIMARY KEY, + CrossIndex INTEGER NOT NULL, + Name VARCHAR NOT NULL, + Description VARCHAR + )""" % self.Table + Table.Create(self, SqlCommand) + + ## Insert table + # + # Insert a record into table DataModel + # + # @param ID: ID of a ModelType + # @param CrossIndex: CrossIndex of a ModelType + # @param Name: Name of a ModelType + # @param Description: Description of a ModelType + # + def Insert(self, CrossIndex, Name, Description): + self.ID = self.ID + 1 + (Name, Description) = ConvertToSqlString((Name, Description)) + SqlCommand = """insert into %s values(%s, %s, '%s', '%s')""" % (self.Table, self.ID, CrossIndex, Name, Description) + Table.Insert(self, SqlCommand) + + return self.ID + + ## Init table + # + # Create all default records of table DataModel + # + def InitTable(self): + EdkLogger.verbose("\nInitialize table DataModel started ...") + for Item in DataClass.MODEL_LIST: + CrossIndex = Item[1] + Name = Item[0] + Description = Item[0] + self.Insert(CrossIndex, Name, Description) + EdkLogger.verbose("Initialize table DataModel ... DONE!") + + ## Get CrossIndex + # + # Get a model's cross index from its name + # + # @param ModelName: Name of the model + # @retval CrossIndex: CrossIndex of the model + # + def GetCrossIndex(self, ModelName): + CrossIndex = -1 + SqlCommand = """select CrossIndex from DataModel where name = '""" + ModelName + """'""" + self.Cur.execute(SqlCommand) + for Item in self.Cur: + CrossIndex = Item[0] + + return CrossIndex diff --git a/BaseTools/Source/Python/Table/TableDec.py b/BaseTools/Source/Python/Table/TableDec.py new file mode 100644 index 0000000000..f570fd1d10 --- /dev/null +++ b/BaseTools/Source/Python/Table/TableDec.py @@ -0,0 +1,108 @@ +## @file +# This file is used to create/update/query/erase table for dec datas +# +# Copyright (c) 2008, 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 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 Common.EdkLogger as EdkLogger +import CommonDataClass.DataClass as DataClass +from Table import Table +from Common.String import ConvertToSqlString + +## TableDec +# +# This class defined a table used for data model +# +# @param object: Inherited from object class +# +# +class TableDec(Table): + def __init__(self, Cursor): + Table.__init__(self, Cursor) + self.Table = 'Dec' + + ## Create table + # + # Create table Dec + # + # @param ID: ID of a Dec item + # @param Model: Model of a Dec item + # @param Value1: Value1 of a Dec item + # @param Value2: Value2 of a Dec item + # @param Value3: Value3 of a Dec item + # @param Arch: Arch of a Dec item + # @param BelongsToItem: The item belongs to which another item + # @param BelongsToFile: The item belongs to which dsc file + # @param StartLine: StartLine of a Dec item + # @param StartColumn: StartColumn of a Dec item + # @param EndLine: EndLine of a Dec item + # @param EndColumn: EndColumn of a Dec item + # @param Enabled: If this item enabled + # + def Create(self): + SqlCommand = """create table IF NOT EXISTS %s (ID INTEGER PRIMARY KEY, + Model INTEGER NOT NULL, + Value1 VARCHAR NOT NULL, + Value2 VARCHAR, + Value3 VARCHAR, + Arch VarCHAR, + BelongsToItem SINGLE NOT NULL, + BelongsToFile SINGLE NOT NULL, + StartLine INTEGER NOT NULL, + StartColumn INTEGER NOT NULL, + EndLine INTEGER NOT NULL, + EndColumn INTEGER NOT NULL, + Enabled INTEGER DEFAULT 0 + )""" % self.Table + Table.Create(self, SqlCommand) + + ## Insert table + # + # Insert a record into table Dec + # + # @param ID: ID of a Dec item + # @param Model: Model of a Dec item + # @param Value1: Value1 of a Dec item + # @param Value2: Value2 of a Dec item + # @param Value3: Value3 of a Dec item + # @param Arch: Arch of a Dec item + # @param BelongsToItem: The item belongs to which another item + # @param BelongsToFile: The item belongs to which dsc file + # @param StartLine: StartLine of a Dec item + # @param StartColumn: StartColumn of a Dec item + # @param EndLine: EndLine of a Dec item + # @param EndColumn: EndColumn of a Dec item + # @param Enabled: If this item enabled + # + def Insert(self, Model, Value1, Value2, Value3, Value4, Value5, Arch, BelongsToItem, BelongsToFile, StartLine, StartColumn, EndLine, EndColumn, Enabled): + self.ID = self.ID + 1 + (Value1, Value2, Value3, Arch) = ConvertToSqlString((Value1, Value2, Value3, Arch)) + SqlCommand = """insert into %s values(%s, %s, '%s', '%s', '%s', '%s', %s, %s, %s, %s, %s, %s, %s)""" \ + % (self.Table, self.ID, Model, Value1, Value2, Value3, Arch, BelongsToItem, BelongsToFile, StartLine, StartColumn, EndLine, EndColumn, Enabled) + Table.Insert(self, SqlCommand) + + return self.ID + + ## Query table + # + # @param Model: The Model of Record + # + # @retval: A recordSet of all found records + # + def Query(self, Model): + SqlCommand = """select ID, Value1, Value2, Value3, Arch, BelongsToItem, BelongsToFile, StartLine from %s + where Model = %s + and Enabled > -1""" % (self.Table, Model) + EdkLogger.debug(4, "SqlCommand: %s" % SqlCommand) + self.Cur.execute(SqlCommand) + return self.Cur.fetchall() diff --git a/BaseTools/Source/Python/Table/TableDsc.py b/BaseTools/Source/Python/Table/TableDsc.py new file mode 100644 index 0000000000..62608a061a --- /dev/null +++ b/BaseTools/Source/Python/Table/TableDsc.py @@ -0,0 +1,108 @@ +## @file +# This file is used to create/update/query/erase table for dsc datas +# +# Copyright (c) 2008, 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 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 Common.EdkLogger as EdkLogger +import CommonDataClass.DataClass as DataClass +from Table import Table +from Common.String import ConvertToSqlString + +## TableDsc +# +# This class defined a table used for data model +# +# @param object: Inherited from object class +# +# +class TableDsc(Table): + def __init__(self, Cursor): + Table.__init__(self, Cursor) + self.Table = 'Dsc' + + ## Create table + # + # Create table Dsc + # + # @param ID: ID of a Dsc item + # @param Model: Model of a Dsc item + # @param Value1: Value1 of a Dsc item + # @param Value2: Value2 of a Dsc item + # @param Value3: Value3 of a Dsc item + # @param Arch: Arch of a Dsc item + # @param BelongsToItem: The item belongs to which another item + # @param BelongsToFile: The item belongs to which dsc file + # @param StartLine: StartLine of a Dsc item + # @param StartColumn: StartColumn of a Dsc item + # @param EndLine: EndLine of a Dsc item + # @param EndColumn: EndColumn of a Dsc item + # @param Enabled: If this item enabled + # + def Create(self): + SqlCommand = """create table IF NOT EXISTS %s (ID INTEGER PRIMARY KEY, + Model INTEGER NOT NULL, + Value1 VARCHAR NOT NULL, + Value2 VARCHAR, + Value3 VARCHAR, + Arch VarCHAR, + BelongsToItem SINGLE NOT NULL, + BelongsToFile SINGLE NOT NULL, + StartLine INTEGER NOT NULL, + StartColumn INTEGER NOT NULL, + EndLine INTEGER NOT NULL, + EndColumn INTEGER NOT NULL, + Enabled INTEGER DEFAULT 0 + )""" % self.Table + Table.Create(self, SqlCommand) + + ## Insert table + # + # Insert a record into table Dsc + # + # @param ID: ID of a Dsc item + # @param Model: Model of a Dsc item + # @param Value1: Value1 of a Dsc item + # @param Value2: Value2 of a Dsc item + # @param Value3: Value3 of a Dsc item + # @param Arch: Arch of a Dsc item + # @param BelongsToItem: The item belongs to which another item + # @param BelongsToFile: The item belongs to which dsc file + # @param StartLine: StartLine of a Dsc item + # @param StartColumn: StartColumn of a Dsc item + # @param EndLine: EndLine of a Dsc item + # @param EndColumn: EndColumn of a Dsc item + # @param Enabled: If this item enabled + # + def Insert(self, Model, Value1, Value2, Value3, Arch, BelongsToItem, BelongsToFile, StartLine, StartColumn, EndLine, EndColumn, Enabled): + self.ID = self.ID + 1 + (Value1, Value2, Value3, Arch) = ConvertToSqlString((Value1, Value2, Value3, Arch)) + SqlCommand = """insert into %s values(%s, %s, '%s', '%s', '%s', '%s', %s, %s, %s, %s, %s, %s, %s)""" \ + % (self.Table, self.ID, Model, Value1, Value2, Value3, Arch, BelongsToItem, BelongsToFile, StartLine, StartColumn, EndLine, EndColumn, Enabled) + Table.Insert(self, SqlCommand) + + return self.ID + + ## Query table + # + # @param Model: The Model of Record + # + # @retval: A recordSet of all found records + # + def Query(self, Model): + SqlCommand = """select ID, Value1, Value2, Value3, Arch, BelongsToItem, BelongsToFile, StartLine from %s + where Model = %s + and Enabled > -1""" % (self.Table, Model) + EdkLogger.debug(4, "SqlCommand: %s" % SqlCommand) + self.Cur.execute(SqlCommand) + return self.Cur.fetchall() diff --git a/BaseTools/Source/Python/Table/TableEotReport.py b/BaseTools/Source/Python/Table/TableEotReport.py new file mode 100644 index 0000000000..cdae3b2e39 --- /dev/null +++ b/BaseTools/Source/Python/Table/TableEotReport.py @@ -0,0 +1,76 @@ +## @file +# This file is used to create/update/query/erase table for ECC reports +# +# Copyright (c) 2008, 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 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 Common.EdkLogger as EdkLogger +import os, time +from Table import Table +from Common.String import ConvertToSqlString2 +import EotToolError as EotToolError +import EotGlobalData as EotGlobalData + +## TableReport +# +# This class defined a table used for data model +# +# @param object: Inherited from object class +# +# +class TableEotReport(Table): + def __init__(self, Cursor): + Table.__init__(self, Cursor) + self.Table = 'Report' + + ## Create table + # + # Create table report + # + # + def Create(self): + SqlCommand = """create table IF NOT EXISTS %s (ID INTEGER PRIMARY KEY, + ModuleID INTEGER DEFAULT -1, + ModuleName TEXT DEFAULT '', + ModuleGuid TEXT DEFAULT '', + SourceFileID INTEGER DEFAULT -1, + SourceFileFullPath TEXT DEFAULT '', + ItemName TEXT DEFAULT '', + ItemType TEXT DEFAULT '', + ItemMode TEXT DEFAULT '', + GuidName TEXT DEFAULT '', + GuidMacro TEXT DEFAULT '', + GuidValue TEXT DEFAULT '', + BelongsToFunction TEXT DEFAULT '', + Enabled INTEGER DEFAULT 0 + )""" % self.Table + Table.Create(self, SqlCommand) + + ## Insert table + # + # Insert a record into table report + # + # + def Insert(self, ModuleID = -1, ModuleName = '', ModuleGuid = '', SourceFileID = -1, SourceFileFullPath = '', \ + ItemName = '', ItemType = '', ItemMode = '', GuidName = '', GuidMacro = '', GuidValue = '', BelongsToFunction = '', Enabled = 0): + self.ID = self.ID + 1 + SqlCommand = """insert into %s values(%s, %s, '%s', '%s', %s, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %s)""" \ + % (self.Table, self.ID, ModuleID, ModuleName, ModuleGuid, SourceFileID, SourceFileFullPath, \ + ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, Enabled) + Table.Insert(self, SqlCommand) + + def GetMaxID(self): + SqlCommand = """select max(ID) from %s""" % self.Table + self.Cur.execute(SqlCommand) + for Item in self.Cur: + return Item[0] \ No newline at end of file diff --git a/BaseTools/Source/Python/Table/TableFdf.py b/BaseTools/Source/Python/Table/TableFdf.py new file mode 100644 index 0000000000..317bd4149b --- /dev/null +++ b/BaseTools/Source/Python/Table/TableFdf.py @@ -0,0 +1,108 @@ +## @file +# This file is used to create/update/query/erase table for fdf datas +# +# Copyright (c) 2008, 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 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 Common.EdkLogger as EdkLogger +import CommonDataClass.DataClass as DataClass +from Table import Table +from Common.String import ConvertToSqlString + +## TableFdf +# +# This class defined a table used for data model +# +# @param object: Inherited from object class +# +# +class TableFdf(Table): + def __init__(self, Cursor): + Table.__init__(self, Cursor) + self.Table = 'Fdf' + + ## Create table + # + # Create table Fdf + # + # @param ID: ID of a Fdf item + # @param Model: Model of a Fdf item + # @param Value1: Value1 of a Fdf item + # @param Value2: Value2 of a Fdf item + # @param Value3: Value3 of a Fdf item + # @param Arch: Arch of a Fdf item + # @param BelongsToItem: The item belongs to which another item + # @param BelongsToFile: The item belongs to which fdf file + # @param StartLine: StartLine of a Fdf item + # @param StartColumn: StartColumn of a Fdf item + # @param EndLine: EndLine of a Fdf item + # @param EndColumn: EndColumn of a Fdf item + # @param Enabled: If this item enabled + # + def Create(self): + SqlCommand = """create table IF NOT EXISTS %s (ID INTEGER PRIMARY KEY, + Model INTEGER NOT NULL, + Value1 VARCHAR NOT NULL, + Value2 VARCHAR, + Value3 VARCHAR, + Arch VarCHAR, + BelongsToItem SINGLE NOT NULL, + BelongsToFile SINGLE NOT NULL, + StartLine INTEGER NOT NULL, + StartColumn INTEGER NOT NULL, + EndLine INTEGER NOT NULL, + EndColumn INTEGER NOT NULL, + Enabled INTEGER DEFAULT 0 + )""" % self.Table + Table.Create(self, SqlCommand) + + ## Insert table + # + # Insert a record into table Fdf + # + # @param ID: ID of a Fdf item + # @param Model: Model of a Fdf item + # @param Value1: Value1 of a Fdf item + # @param Value2: Value2 of a Fdf item + # @param Value3: Value3 of a Fdf item + # @param Arch: Arch of a Fdf item + # @param BelongsToItem: The item belongs to which another item + # @param BelongsToFile: The item belongs to which fdf file + # @param StartLine: StartLine of a Fdf item + # @param StartColumn: StartColumn of a Fdf item + # @param EndLine: EndLine of a Fdf item + # @param EndColumn: EndColumn of a Fdf item + # @param Enabled: If this item enabled + # + def Insert(self, Model, Value1, Value2, Value3, Arch, BelongsToItem, BelongsToFile, StartLine, StartColumn, EndLine, EndColumn, Enabled): + self.ID = self.ID + 1 + (Value1, Value2, Value3, Arch) = ConvertToSqlString((Value1, Value2, Value3, Arch)) + SqlCommand = """insert into %s values(%s, %s, '%s', '%s', '%s', '%s', %s, %s, %s, %s, %s, %s, %s)""" \ + % (self.Table, self.ID, Model, Value1, Value2, Value3, Arch, BelongsToItem, BelongsToFile, StartLine, StartColumn, EndLine, EndColumn, Enabled) + Table.Insert(self, SqlCommand) + + return self.ID + + ## Query table + # + # @param Model: The Model of Record + # + # @retval: A recordSet of all found records + # + def Query(self, Model): + SqlCommand = """select ID, Value1, Value2, Value3, Arch, BelongsToItem, BelongsToFile, StartLine from %s + where Model = %s + and Enabled > -1""" % (self.Table, Model) + EdkLogger.debug(4, "SqlCommand: %s" % SqlCommand) + self.Cur.execute(SqlCommand) + return self.Cur.fetchall() diff --git a/BaseTools/Source/Python/Table/TableFile.py b/BaseTools/Source/Python/Table/TableFile.py new file mode 100644 index 0000000000..9be64942ec --- /dev/null +++ b/BaseTools/Source/Python/Table/TableFile.py @@ -0,0 +1,91 @@ +## @file +# This file is used to create/update/query/erase table for files +# +# Copyright (c) 2008, 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 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 Common.EdkLogger as EdkLogger +from Table import Table +from Common.String import ConvertToSqlString +import os +from CommonDataClass.DataClass import FileClass + +## TableFile +# +# This class defined a table used for file +# +# @param object: Inherited from object class +# +class TableFile(Table): + def __init__(self, Cursor): + Table.__init__(self, Cursor) + self.Table = 'File' + + ## Create table + # + # Create table File + # + # @param ID: ID of a File + # @param Name: Name of a File + # @param ExtName: ExtName of a File + # @param Path: Path of a File + # @param FullPath: FullPath of a File + # @param Model: Model of a File + # @param TimeStamp: TimeStamp of a File + # + def Create(self): + SqlCommand = """create table IF NOT EXISTS %s (ID INTEGER PRIMARY KEY, + Name VARCHAR NOT NULL, + ExtName VARCHAR, + Path VARCHAR, + FullPath VARCHAR NOT NULL, + Model INTEGER DEFAULT 0, + TimeStamp VARCHAR NOT NULL + )""" % self.Table + Table.Create(self, SqlCommand) + + ## Insert table + # + # Insert a record into table File + # + # @param ID: ID of a File + # @param Name: Name of a File + # @param ExtName: ExtName of a File + # @param Path: Path of a File + # @param FullPath: FullPath of a File + # @param Model: Model of a File + # @param TimeStamp: TimeStamp of a File + # + def Insert(self, Name, ExtName, Path, FullPath, Model, TimeStamp): + self.ID = self.ID + 1 + (Name, ExtName, Path, FullPath) = ConvertToSqlString((Name, ExtName, Path, FullPath)) + SqlCommand = """insert into %s values(%s, '%s', '%s', '%s', '%s', %s, '%s')""" \ + % (self.Table, self.ID, Name, ExtName, Path, FullPath, Model, TimeStamp) + Table.Insert(self, SqlCommand) + + return self.ID + ## InsertFile + # + # Insert one file to table + # + # @param FileFullPath: The full path of the file + # @param Model: The model of the file + # + # @retval FileID: The ID after record is inserted + # + def InsertFile(self, FileFullPath, Model): + (Filepath, Name) = os.path.split(FileFullPath) + (Root, Ext) = os.path.splitext(FileFullPath) + TimeStamp = os.stat(FileFullPath)[8] + File = FileClass(-1, Name, Ext, Filepath, FileFullPath, Model, '', [], [], []) + return self.Insert(File.Name, File.ExtName, File.Path, File.FullPath, File.Model, TimeStamp) diff --git a/BaseTools/Source/Python/Table/TableFunction.py b/BaseTools/Source/Python/Table/TableFunction.py new file mode 100644 index 0000000000..c013d0d2fe --- /dev/null +++ b/BaseTools/Source/Python/Table/TableFunction.py @@ -0,0 +1,95 @@ +## @file +# This file is used to create/update/query/erase table for functions +# +# Copyright (c) 2008, 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 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 Common.EdkLogger as EdkLogger +from Table import Table +from Common.String import ConvertToSqlString + +## TableFunction +# +# This class defined a table used for function +# +# @param Table: Inherited from Table class +# +class TableFunction(Table): + def __init__(self, Cursor): + Table.__init__(self, Cursor) + self.Table = 'Function' + + ## Create table + # + # Create table Function + # + # @param ID: ID of a Function + # @param Header: Header of a Function + # @param Modifier: Modifier of a Function + # @param Name: Name of a Function + # @param ReturnStatement: ReturnStatement of a Funciont + # @param StartLine: StartLine of a Function + # @param StartColumn: StartColumn of a Function + # @param EndLine: EndLine of a Function + # @param EndColumn: EndColumn of a Function + # @param BodyStartLine: StartLine of a Function body + # @param BodyStartColumn: StartColumn of a Function body + # @param BelongsToFile: The Function belongs to which file + # @param FunNameStartLine: StartLine of a Function name + # @param FunNameStartColumn: StartColumn of a Function name + # + def Create(self): + SqlCommand = """create table IF NOT EXISTS %s (ID INTEGER PRIMARY KEY, + Header TEXT, + Modifier VARCHAR, + Name VARCHAR NOT NULL, + ReturnStatement VARCHAR, + StartLine INTEGER NOT NULL, + StartColumn INTEGER NOT NULL, + EndLine INTEGER NOT NULL, + EndColumn INTEGER NOT NULL, + BodyStartLine INTEGER NOT NULL, + BodyStartColumn INTEGER NOT NULL, + BelongsToFile SINGLE NOT NULL, + FunNameStartLine INTEGER NOT NULL, + FunNameStartColumn INTEGER NOT NULL + )""" % self.Table + Table.Create(self, SqlCommand) + + ## Insert table + # + # Insert a record into table Function + # + # @param ID: ID of a Function + # @param Header: Header of a Function + # @param Modifier: Modifier of a Function + # @param Name: Name of a Function + # @param ReturnStatement: ReturnStatement of a Funciont + # @param StartLine: StartLine of a Function + # @param StartColumn: StartColumn of a Function + # @param EndLine: EndLine of a Function + # @param EndColumn: EndColumn of a Function + # @param BodyStartLine: StartLine of a Function body + # @param BodyStartColumn: StartColumn of a Function body + # @param BelongsToFile: The Function belongs to which file + # @param FunNameStartLine: StartLine of a Function name + # @param FunNameStartColumn: StartColumn of a Function name + # + def Insert(self, Header, Modifier, Name, ReturnStatement, StartLine, StartColumn, EndLine, EndColumn, BodyStartLine, BodyStartColumn, BelongsToFile, FunNameStartLine, FunNameStartColumn): + self.ID = self.ID + 1 + (Header, Modifier, Name, ReturnStatement) = ConvertToSqlString((Header, Modifier, Name, ReturnStatement)) + SqlCommand = """insert into %s values(%s, '%s', '%s', '%s', '%s', %s, %s, %s, %s, %s, %s, %s, %s, %s)""" \ + % (self.Table, self.ID, Header, Modifier, Name, ReturnStatement, StartLine, StartColumn, EndLine, EndColumn, BodyStartLine, BodyStartColumn, BelongsToFile, FunNameStartLine, FunNameStartColumn) + Table.Insert(self, SqlCommand) + + return self.ID diff --git a/BaseTools/Source/Python/Table/TableIdentifier.py b/BaseTools/Source/Python/Table/TableIdentifier.py new file mode 100644 index 0000000000..3cf33f20e2 --- /dev/null +++ b/BaseTools/Source/Python/Table/TableIdentifier.py @@ -0,0 +1,90 @@ +## @file +# This file is used to create/update/query/erase table for Identifiers +# +# Copyright (c) 2008, 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 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 Common.EdkLogger as EdkLogger +from Common.String import ConvertToSqlString +from Table import Table + +## TableIdentifier +# +# This class defined a table used for Identifier +# +# @param object: Inherited from object class +# +# +class TableIdentifier(Table): + def __init__(self, Cursor): + Table.__init__(self, Cursor) + self.Table = 'Identifier' + + ## Create table + # + # Create table Identifier + # + # @param ID: ID of a Identifier + # @param Modifier: Modifier of a Identifier + # @param Type: Type of a Identifier + # @param Name: Name of a Identifier + # @param Value: Value of a Identifier + # @param Model: Model of a Identifier + # @param BelongsToFile: The Identifier belongs to which file + # @param BelongsToFunction: The Identifier belongs to which function + # @param StartLine: StartLine of a Identifier + # @param StartColumn: StartColumn of a Identifier + # @param EndLine: EndLine of a Identifier + # @param EndColumn: EndColumn of a Identifier + # + def Create(self): + SqlCommand = """create table IF NOT EXISTS %s(ID INTEGER PRIMARY KEY, + Modifier VARCHAR, + Type VARCHAR, + Name VARCHAR NOT NULL, + Value VARCHAR NOT NULL, + Model INTEGER NOT NULL, + BelongsToFile SINGLE NOT NULL, + BelongsToFunction SINGLE DEFAULT -1, + StartLine INTEGER NOT NULL, + StartColumn INTEGER NOT NULL, + EndLine INTEGER NOT NULL, + EndColumn INTEGER NOT NULL + )""" % self.Table + Table.Create(self, SqlCommand) + + ## Insert table + # + # Insert a record into table Identifier + # + # @param ID: ID of a Identifier + # @param Modifier: Modifier of a Identifier + # @param Type: Type of a Identifier + # @param Name: Name of a Identifier + # @param Value: Value of a Identifier + # @param Model: Model of a Identifier + # @param BelongsToFile: The Identifier belongs to which file + # @param BelongsToFunction: The Identifier belongs to which function + # @param StartLine: StartLine of a Identifier + # @param StartColumn: StartColumn of a Identifier + # @param EndLine: EndLine of a Identifier + # @param EndColumn: EndColumn of a Identifier + # + def Insert(self, Modifier, Type, Name, Value, Model, BelongsToFile, BelongsToFunction, StartLine, StartColumn, EndLine, EndColumn): + self.ID = self.ID + 1 + (Modifier, Type, Name, Value) = ConvertToSqlString((Modifier, Type, Name, Value)) + SqlCommand = """insert into %s values(%s, '%s', '%s', '%s', '%s', %s, %s, %s, %s, %s, %s, %s)""" \ + % (self.Table, self.ID, Modifier, Type, Name, Value, Model, BelongsToFile, BelongsToFunction, StartLine, StartColumn, EndLine, EndColumn) + Table.Insert(self, SqlCommand) + + return self.ID \ No newline at end of file diff --git a/BaseTools/Source/Python/Table/TableInf.py b/BaseTools/Source/Python/Table/TableInf.py new file mode 100644 index 0000000000..65ca1ce25c --- /dev/null +++ b/BaseTools/Source/Python/Table/TableInf.py @@ -0,0 +1,114 @@ +## @file +# This file is used to create/update/query/erase table for inf datas +# +# Copyright (c) 2008, 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 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 Common.EdkLogger as EdkLogger +import CommonDataClass.DataClass as DataClass +from Table import Table +from Common.String import ConvertToSqlString + +## TableInf +# +# This class defined a table used for data model +# +# @param object: Inherited from object class +# +# +class TableInf(Table): + def __init__(self, Cursor): + Table.__init__(self, Cursor) + self.Table = 'Inf' + + ## Create table + # + # Create table Inf + # + # @param ID: ID of a Inf item + # @param Model: Model of a Inf item + # @param Value1: Value1 of a Inf item + # @param Value2: Value2 of a Inf item + # @param Value3: Value3 of a Inf item + # @param Value4: Value4 of a Inf item + # @param Value5: Value5 of a Inf item + # @param Arch: Arch of a Inf item + # @param BelongsToItem: The item belongs to which another item + # @param BelongsToFile: The item belongs to which dsc file + # @param StartLine: StartLine of a Inf item + # @param StartColumn: StartColumn of a Inf item + # @param EndLine: EndLine of a Inf item + # @param EndColumn: EndColumn of a Inf item + # @param Enabled: If this item enabled + # + def Create(self): + SqlCommand = """create table IF NOT EXISTS %s (ID INTEGER PRIMARY KEY, + Model INTEGER NOT NULL, + Value1 VARCHAR NOT NULL, + Value2 VARCHAR, + Value3 VARCHAR, + Value4 VARCHAR, + Value5 VARCHAR, + Arch VarCHAR, + BelongsToItem SINGLE NOT NULL, + BelongsToFile SINGLE NOT NULL, + StartLine INTEGER NOT NULL, + StartColumn INTEGER NOT NULL, + EndLine INTEGER NOT NULL, + EndColumn INTEGER NOT NULL, + Enabled INTEGER DEFAULT 0 + )""" % self.Table + Table.Create(self, SqlCommand) + + ## Insert table + # + # Insert a record into table Inf + # + # @param ID: ID of a Inf item + # @param Model: Model of a Inf item + # @param Value1: Value1 of a Inf item + # @param Value2: Value2 of a Inf item + # @param Value3: Value3 of a Inf item + # @param Value4: Value4 of a Inf item + # @param Value5: Value5 of a Inf item + # @param Arch: Arch of a Inf item + # @param BelongsToItem: The item belongs to which another item + # @param BelongsToFile: The item belongs to which dsc file + # @param StartLine: StartLine of a Inf item + # @param StartColumn: StartColumn of a Inf item + # @param EndLine: EndLine of a Inf item + # @param EndColumn: EndColumn of a Inf item + # @param Enabled: If this item enabled + # + def Insert(self, Model, Value1, Value2, Value3, Value4, Value5, Arch, BelongsToItem, BelongsToFile, StartLine, StartColumn, EndLine, EndColumn, Enabled): + self.ID = self.ID + 1 + (Value1, Value2, Value3, Value4, Value5, Arch) = ConvertToSqlString((Value1, Value2, Value3, Value4, Value5, Arch)) + SqlCommand = """insert into %s values(%s, %s, '%s', '%s', '%s', '%s', '%s', '%s', %s, %s, %s, %s, %s, %s, %s)""" \ + % (self.Table, self.ID, Model, Value1, Value2, Value3, Value4, Value5, Arch, BelongsToItem, BelongsToFile, StartLine, StartColumn, EndLine, EndColumn, Enabled) + Table.Insert(self, SqlCommand) + + return self.ID + + ## Query table + # + # @param Model: The Model of Record + # + # @retval: A recordSet of all found records + # + def Query(self, Model): + SqlCommand = """select ID, Value1, Value2, Value3, Arch, BelongsToItem, BelongsToFile, StartLine from %s + where Model = %s + and Enabled > -1""" % (self.Table, Model) + EdkLogger.debug(4, "SqlCommand: %s" % SqlCommand) + self.Cur.execute(SqlCommand) + return self.Cur.fetchall() diff --git a/BaseTools/Source/Python/Table/TablePcd.py b/BaseTools/Source/Python/Table/TablePcd.py new file mode 100644 index 0000000000..ba91d175f0 --- /dev/null +++ b/BaseTools/Source/Python/Table/TablePcd.py @@ -0,0 +1,90 @@ +## @file +# This file is used to create/update/query/erase table for pcds +# +# Copyright (c) 2008, 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 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 Common.EdkLogger as EdkLogger +from Table import Table +from Common.String import ConvertToSqlString + +## TablePcd +# +# This class defined a table used for pcds +# +# @param object: Inherited from object class +# +# +class TablePcd(Table): + def __init__(self, Cursor): + Table.__init__(self, Cursor) + self.Table = 'Pcd' + + ## Create table + # + # Create table Pcd + # + # @param ID: ID of a Pcd + # @param CName: CName of a Pcd + # @param TokenSpaceGuidCName: TokenSpaceGuidCName of a Pcd + # @param Token: Token of a Pcd + # @param DatumType: DatumType of a Pcd + # @param Model: Model of a Pcd + # @param BelongsToFile: The Pcd belongs to which file + # @param BelongsToFunction: The Pcd belongs to which function + # @param StartLine: StartLine of a Pcd + # @param StartColumn: StartColumn of a Pcd + # @param EndLine: EndLine of a Pcd + # @param EndColumn: EndColumn of a Pcd + # + def Create(self): + SqlCommand = """create table IF NOT EXISTS %s (ID INTEGER PRIMARY KEY, + CName VARCHAR NOT NULL, + TokenSpaceGuidCName VARCHAR NOT NULL, + Token INTEGER, + DatumType VARCHAR, + Model INTEGER NOT NULL, + BelongsToFile SINGLE NOT NULL, + BelongsToFunction SINGLE DEFAULT -1, + StartLine INTEGER NOT NULL, + StartColumn INTEGER NOT NULL, + EndLine INTEGER NOT NULL, + EndColumn INTEGER NOT NULL + )""" % self.Table + Table.Create(self, SqlCommand) + + ## Insert table + # + # Insert a record into table Pcd + # + # @param ID: ID of a Pcd + # @param CName: CName of a Pcd + # @param TokenSpaceGuidCName: TokenSpaceGuidCName of a Pcd + # @param Token: Token of a Pcd + # @param DatumType: DatumType of a Pcd + # @param Model: Model of a Pcd + # @param BelongsToFile: The Pcd belongs to which file + # @param BelongsToFunction: The Pcd belongs to which function + # @param StartLine: StartLine of a Pcd + # @param StartColumn: StartColumn of a Pcd + # @param EndLine: EndLine of a Pcd + # @param EndColumn: EndColumn of a Pcd + # + def Insert(self, CName, TokenSpaceGuidCName, Token, DatumType, Model, BelongsToFile, BelongsToFunction, StartLine, StartColumn, EndLine, EndColumn): + self.ID = self.ID + 1 + (CName, TokenSpaceGuidCName, DatumType) = ConvertToSqlString((CName, TokenSpaceGuidCName, DatumType)) + SqlCommand = """insert into %s values(%s, '%s', '%s', %s, '%s', %s, %s, %s, %s, %s, %s, %s)""" \ + % (self.Table, self.ID, CName, TokenSpaceGuidCName, Token, DatumType, Model, BelongsToFile, BelongsToFunction, StartLine, StartColumn, EndLine, EndColumn) + Table.Insert(self, SqlCommand) + + return self.ID \ No newline at end of file diff --git a/BaseTools/Source/Python/Table/TableQuery.py b/BaseTools/Source/Python/Table/TableQuery.py new file mode 100644 index 0000000000..9a9a66ccb6 --- /dev/null +++ b/BaseTools/Source/Python/Table/TableQuery.py @@ -0,0 +1,66 @@ +## @file +# This file is used to create/update/query/erase table for Queries +# +# Copyright (c) 2008, 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 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 Common.EdkLogger as EdkLogger +from Common.String import ConvertToSqlString +from Table import Table + +## TableQuery +# +# This class defined a table used for Query +# +# @param object: Inherited from object class +# +# +class TableQuery(Table): + def __init__(self, Cursor): + Table.__init__(self, Cursor) + self.Table = 'Query' + + ## Create table + # + # Create table Query + # + # @param ID: ID of a Query + # @param Name: Modifier of a Query + # @param Value: Type of a Query + # @param Model: Model of a Query + # + def Create(self): + SqlCommand = """create table IF NOT EXISTS %s(ID INTEGER PRIMARY KEY, + Name TEXT DEFAULT '', + Value TEXT DEFAULT '', + Model INTEGER DEFAULT 0 + )""" % self.Table + Table.Create(self, SqlCommand) + + ## Insert table + # + # Insert a record into table Query + # + # @param ID: ID of a Query + # @param Name: Modifier of a Query + # @param Value: Type of a Query + # @param Model: Model of a Query + # + def Insert(self, Name, Value, Model): + self.ID = self.ID + 1 + SqlCommand = """insert into %s values(%s, '%s', '%s', %s)""" \ + % (self.Table, self.ID, Name, Value, Model) + Table.Insert(self, SqlCommand) + + return self.ID + \ No newline at end of file diff --git a/BaseTools/Source/Python/Table/TableReport.py b/BaseTools/Source/Python/Table/TableReport.py new file mode 100644 index 0000000000..042c1b7e9e --- /dev/null +++ b/BaseTools/Source/Python/Table/TableReport.py @@ -0,0 +1,123 @@ +## @file +# This file is used to create/update/query/erase table for ECC reports +# +# Copyright (c) 2008, 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 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 Common.EdkLogger as EdkLogger +import os, time +from Table import Table +from Common.String import ConvertToSqlString2 +import EccToolError as EccToolError +import EccGlobalData as EccGlobalData + +## TableReport +# +# This class defined a table used for data model +# +# @param object: Inherited from object class +# +# +class TableReport(Table): + def __init__(self, Cursor): + Table.__init__(self, Cursor) + self.Table = 'Report' + + ## Create table + # + # Create table report + # + # @param ID: ID of an Error + # @param ErrorID: ID of an Error TypeModel of a Report item + # @param OtherMsg: Other error message besides the standard error message + # @param BelongsToItem: The error belongs to which item + # @param Enabled: If this error enabled + # @param Corrected: if this error corrected + # + def Create(self): + SqlCommand = """create table IF NOT EXISTS %s (ID INTEGER PRIMARY KEY, + ErrorID INTEGER NOT NULL, + OtherMsg TEXT, + BelongsToTable TEXT NOT NULL, + BelongsToItem SINGLE NOT NULL, + Enabled INTEGER DEFAULT 0, + Corrected INTEGER DEFAULT -1 + )""" % self.Table + Table.Create(self, SqlCommand) + + ## Insert table + # + # Insert a record into table report + # + # @param ID: ID of an Error + # @param ErrorID: ID of an Error TypeModel of a report item + # @param OtherMsg: Other error message besides the standard error message + # @param BelongsToTable: The error item belongs to which table + # @param BelongsToItem: The error belongs to which item + # @param Enabled: If this error enabled + # @param Corrected: if this error corrected + # + def Insert(self, ErrorID, OtherMsg = '', BelongsToTable = '', BelongsToItem = -1, Enabled = 0, Corrected = -1): + self.ID = self.ID + 1 + SqlCommand = """insert into %s values(%s, %s, '%s', '%s', %s, %s, %s)""" \ + % (self.Table, self.ID, ErrorID, ConvertToSqlString2(OtherMsg), BelongsToTable, BelongsToItem, Enabled, Corrected) + Table.Insert(self, SqlCommand) + + return self.ID + + ## Query table + # + # @retval: A recordSet of all found records + # + def Query(self): + SqlCommand = """select ID, ErrorID, OtherMsg, BelongsToTable, BelongsToItem, Corrected from %s + where Enabled > -1 order by ErrorID, BelongsToItem""" % (self.Table) + return self.Exec(SqlCommand) + + ## Convert to CSV + # + # Get all enabled records from table report and save them to a .csv file + # + # @param Filename: To filename to save the report content + # + def ToCSV(self, Filename = 'Report.csv'): + try: + File = open(Filename, 'w+') + File.write("""No, Error Code, Error Message, File, LineNo, Other Error Message\n""") + RecordSet = self.Query() + Index = 0 + for Record in RecordSet: + Index = Index + 1 + ErrorID = Record[1] + OtherMsg = Record[2] + BelongsToTable = Record[3] + BelongsToItem = Record[4] + IsCorrected = Record[5] + SqlCommand = '' + if BelongsToTable == 'File': + SqlCommand = """select 0, FullPath from %s where ID = %s + """ % (BelongsToTable, BelongsToItem) + else: + SqlCommand = """select A.StartLine, B.FullPath from %s as A, File as B + where A.ID = %s and B.ID = A.BelongsToFile + """ % (BelongsToTable, BelongsToItem) + NewRecord = self.Exec(SqlCommand) + if NewRecord != []: + File.write("""%s,%s,"%s",%s,%s,"%s"\n""" % (Index, ErrorID, EccToolError.gEccErrorMessage[ErrorID], NewRecord[0][1], NewRecord[0][0], OtherMsg)) + + File.close() + except IOError: + NewFilename = 'Report_' + time.strftime("%Y%m%d_%H%M%S.csv", time.localtime()) + EdkLogger.warn("ECC", "The report file %s is locked by other progress, use %s instead!" % (Filename, NewFilename)) + self.ToCSV(NewFilename) + diff --git a/BaseTools/Source/Python/Table/__init__.py b/BaseTools/Source/Python/Table/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/BaseTools/Source/Python/TargetTool/TargetTool.py b/BaseTools/Source/Python/TargetTool/TargetTool.py new file mode 100644 index 0000000000..69cac95d4f --- /dev/null +++ b/BaseTools/Source/Python/TargetTool/TargetTool.py @@ -0,0 +1,261 @@ +# +# Copyright (c) 2007, 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 accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# + +import os +import sys +import traceback +from optparse import OptionParser + +import Common.EdkLogger as EdkLogger +import Common.BuildToolError as BuildToolError +from Common.DataType import * + +# To Do 1.set clean, 2. add item, if the line is disabled. + +class TargetTool(): + def __init__(self, opt, args): + self.WorkSpace = os.path.normpath(os.getenv('WORKSPACE')) + self.Opt = opt + self.Arg = args[0] + self.FileName = os.path.normpath(os.path.join(self.WorkSpace, 'Conf', 'target.txt')) + if os.path.isfile(self.FileName) == False: + print "%s does not exist." % self.FileName + sys.exit(1) + self.TargetTxtDictionary = { + TAB_TAT_DEFINES_ACTIVE_PLATFORM : None, + TAB_TAT_DEFINES_TOOL_CHAIN_CONF : None, + TAB_TAT_DEFINES_MULTIPLE_THREAD : None, + TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER : None, + TAB_TAT_DEFINES_TARGET : None, + TAB_TAT_DEFINES_TOOL_CHAIN_TAG : None, + TAB_TAT_DEFINES_TARGET_ARCH : None, + TAB_TAT_DEFINES_BUILD_RULE_CONF : None, + } + self.LoadTargetTxtFile(self.FileName) + + def LoadTargetTxtFile(self, filename): + if os.path.exists(filename) and os.path.isfile(filename): + return self.ConvertTextFileToDict(filename, '#', '=') + else: + raise ParseError('LoadTargetTxtFile() : No Target.txt file exists.') + return 1 + +# +# Convert a text file to a dictionary +# + def ConvertTextFileToDict(self, FileName, CommentCharacter, KeySplitCharacter): + """Convert a text file to a dictionary of (name:value) pairs.""" + try: + f = open(FileName,'r') + for Line in f: + if Line.startswith(CommentCharacter) or Line.strip() == '': + continue + LineList = Line.split(KeySplitCharacter,1) + if len(LineList) >= 2: + Key = LineList[0].strip() + if Key.startswith(CommentCharacter) == False and Key in self.TargetTxtDictionary.keys(): + if Key == TAB_TAT_DEFINES_ACTIVE_PLATFORM or Key == TAB_TAT_DEFINES_TOOL_CHAIN_CONF \ + or Key == TAB_TAT_DEFINES_MULTIPLE_THREAD or Key == TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER \ + or Key == TAB_TAT_DEFINES_ACTIVE_MODULE: + self.TargetTxtDictionary[Key] = LineList[1].replace('\\', '/').strip() + elif Key == TAB_TAT_DEFINES_TARGET or Key == TAB_TAT_DEFINES_TARGET_ARCH \ + or Key == TAB_TAT_DEFINES_TOOL_CHAIN_TAG or Key == TAB_TAT_DEFINES_BUILD_RULE_CONF: + self.TargetTxtDictionary[Key] = LineList[1].split() + f.close() + return 0 + except: + last_type, last_value, last_tb = sys.exc_info() + traceback.print_exception(last_type, last_value, last_tb) + + def Print(self): + KeyList = self.TargetTxtDictionary.keys() + errMsg = '' + for Key in KeyList: + if type(self.TargetTxtDictionary[Key]) == type([]): + print "%-30s = %s" % (Key, ''.join(elem + ' ' for elem in self.TargetTxtDictionary[Key])) + elif self.TargetTxtDictionary[Key] == None: + errMsg += " Missing %s configuration information, please use TargetTool to set value!" % Key + os.linesep + else: + print "%-30s = %s" % (Key, self.TargetTxtDictionary[Key]) + + if errMsg != '': + print os.linesep + 'Warning:' + os.linesep + errMsg + + def RWFile(self, CommentCharacter, KeySplitCharacter, Num): + try: + fr = open(self.FileName, 'r') + fw = open(os.path.normpath(os.path.join(self.WorkSpace, 'Conf\\targetnew.txt')), 'w') + + existKeys = [] + for Line in fr: + if Line.startswith(CommentCharacter) or Line.strip() == '': + fw.write(Line) + else: + LineList = Line.split(KeySplitCharacter,1) + if len(LineList) >= 2: + Key = LineList[0].strip() + if Key.startswith(CommentCharacter) == False and Key in self.TargetTxtDictionary.keys(): + if Key not in existKeys: + existKeys.append(Key) + else: + print "Warning: Found duplicate key item in original configuration files!" + + if Num == 0: + Line = "%-30s = \n" % Key + else: + ret = GetConfigureKeyValue(self, Key) + if ret != None: + Line = ret + fw.write(Line) + for key in self.TargetTxtDictionary.keys(): + if key not in existKeys: + print "Warning: %s does not exist in original configuration file" % key + Line = GetConfigureKeyValue(self, key) + if Line == None: + Line = "%-30s = " % key + fw.write(Line) + + fr.close() + fw.close() + os.remove(self.FileName) + os.rename(os.path.normpath(os.path.join(self.WorkSpace, 'Conf\\targetnew.txt')), self.FileName) + + except: + last_type, last_value, last_tb = sys.exc_info() + traceback.print_exception(last_type, last_value, last_tb) + +def GetConfigureKeyValue(self, Key): + Line = None + if Key == TAB_TAT_DEFINES_ACTIVE_PLATFORM and self.Opt.DSCFILE != None: + dscFullPath = os.path.join(self.WorkSpace, self.Opt.DSCFILE) + if os.path.exists(dscFullPath): + Line = "%-30s = %s\n" % (Key, self.Opt.DSCFILE) + else: + EdkLogger.error("TagetTool", BuildToolError.FILE_NOT_FOUND, + "DSC file %s does not exist!" % self.Opt.DSCFILE, RaiseError=False) + elif Key == TAB_TAT_DEFINES_TOOL_CHAIN_CONF and self.Opt.TOOL_DEFINITION_FILE != None: + tooldefFullPath = os.path.join(self.WorkSpace, self.Opt.TOOL_DEFINITION_FILE) + if os.path.exists(tooldefFullPath): + Line = "%-30s = %s\n" % (Key, self.Opt.TOOL_DEFINITION_FILE) + else: + EdkLogger.error("TagetTool", BuildToolError.FILE_NOT_FOUND, + "Tooldef file %s does not exist!" % self.Opt.TOOL_DEFINITION_FILE, RaiseError=False) + elif Key == TAB_TAT_DEFINES_MULTIPLE_THREAD and self.Opt.NUM != None: + if self.Opt.NUM >= 2: + Line = "%-30s = %s\n" % (Key, 'Enable') + else: + Line = "%-30s = %s\n" % (Key, 'Disable') + elif Key == TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER and self.Opt.NUM != None: + Line = "%-30s = %s\n" % (Key, str(self.Opt.NUM)) + elif Key == TAB_TAT_DEFINES_MULTIPLE_THREAD and self.Opt.ENABLE_MULTI_THREAD != None: + Line = "%-30s = %s\n" % (Key, self.Opt.ENABLE_MULTI_THREAD) + elif Key == TAB_TAT_DEFINES_TARGET and self.Opt.TARGET != None: + Line = "%-30s = %s\n" % (Key, ''.join(elem + ' ' for elem in self.Opt.TARGET)) + elif Key == TAB_TAT_DEFINES_TARGET_ARCH and self.Opt.TARGET_ARCH != None: + Line = "%-30s = %s\n" % (Key, ''.join(elem + ' ' for elem in self.Opt.TARGET_ARCH)) + elif Key == TAB_TAT_DEFINES_TOOL_CHAIN_TAG and self.Opt.TOOL_CHAIN_TAG != None: + Line = "%-30s = %s\n" % (Key, self.Opt.TOOL_CHAIN_TAG) + elif Key == TAB_TAT_DEFINES_BUILD_RULE_CONF and self.Opt.BUILD_RULE_FILE != None: + buildruleFullPath = os.path.join(self.WorkSpace, self.Opt.BUILD_RULE_FILE) + if os.path.exists(buildruleFullPath): + Line = "%-30s = %s\n" % (Key, self.Opt.BUILD_RULE_FILE) + else: + EdkLogger.error("TagetTool", BuildToolError.FILE_NOT_FOUND, + "Build rule file %s does not exist!" % self.Opt.BUILD_RULE_FILE, RaiseError=False) + return Line + +VersionNumber = "0.01" +__version__ = "%prog Version " + VersionNumber +__copyright__ = "Copyright (c) 2007, Intel Corporation All rights reserved." +__usage__ = "%prog [options] {args} \ +\nArgs: \ +\n Clean clean the all default configuration of target.txt. \ +\n Print print the all default configuration of target.txt. \ +\n Set replace the default configuration with expected value specified by option." + +gParamCheck = [] +def SingleCheckCallback(option, opt_str, value, parser): + if option not in gParamCheck: + setattr(parser.values, option.dest, value) + gParamCheck.append(option) + else: + parser.error("Option %s only allows one instance in command line!" % option) + +def RangeCheckCallback(option, opt_str, value, parser): + if option not in gParamCheck: + gParamCheck.append(option) + if value < 1 or value > 8: + parser.error("The count of multi-thread is not in valid range of 1 ~ 8.") + else: + setattr(parser.values, option.dest, value) + else: + parser.error("Option %s only allows one instance in command line!" % option) + +def MyOptionParser(): + parser = OptionParser(version=__version__,prog="TargetTool.exe",usage=__usage__,description=__copyright__) + parser.add_option("-a", "--arch", action="append", type="choice", choices=['IA32','X64','IPF','EBC', 'ARM','0'], dest="TARGET_ARCH", + help="ARCHS is one of list: IA32, X64, IPF, ARM or EBC, which replaces target.txt's TARGET_ARCH definition. To specify more archs, please repeat this option. 0 will clear this setting in target.txt and can't combine with other value.") + parser.add_option("-p", "--platform", action="callback", type="string", dest="DSCFILE", callback=SingleCheckCallback, + help="Specify a DSC file, which replace target.txt's ACTIVE_PLATFORM definition. 0 will clear this setting in target.txt and can't combine with other value.") + parser.add_option("-c", "--tooldef", action="callback", type="string", dest="TOOL_DEFINITION_FILE", callback=SingleCheckCallback, + help="Specify the WORKSPACE relative path of tool_def.txt file, which replace target.txt's TOOL_CHAIN_CONF definition. 0 will clear this setting in target.txt and can't combine with other value.") + parser.add_option("-t", "--target", action="append", type="choice", choices=['DEBUG','RELEASE','0'], dest="TARGET", + help="TARGET is one of list: DEBUG, RELEASE, which replaces target.txt's TARGET definition. To specify more TARGET, please repeat this option. 0 will clear this setting in target.txt and can't combine with other value.") + parser.add_option("-n", "--tagname", action="callback", type="string", dest="TOOL_CHAIN_TAG", callback=SingleCheckCallback, + help="Specify the Tool Chain Tagname, which replaces target.txt's TOOL_CHAIN_TAG definition. 0 will clear this setting in target.txt and can't combine with other value.") + parser.add_option("-r", "--buildrule", action="callback", type="string", dest="BUILD_RULE_FILE", callback=SingleCheckCallback, + help="Specify the build rule configure file, which replaces target.txt's BUILD_RULE_CONF definition. If not specified, the default value Conf/build_rule.txt will be set.") + parser.add_option("-m", "--multithreadnum", action="callback", type="int", dest="NUM", callback=RangeCheckCallback, + help="Specify the multi-thread number which replace target.txt's MAX_CONCURRENT_THREAD_NUMBER. If the value is less than 2, MULTIPLE_THREAD will be disabled. If the value is larger than 1, MULTIPLE_THREAD will be enabled.") + parser.add_option("-e", "--enablemultithread", action="store", type="choice", choices=['Enable', 'Disable'], dest="ENABLE_MULTI_THREAD", + help="Specify whether enable multi-thread! If Enable, multi-thread is enabled; If Disable, mutli-thread is disable") + (opt, args)=parser.parse_args() + return (opt, args) + +if __name__ == '__main__': + EdkLogger.Initialize() + EdkLogger.SetLevel(EdkLogger.QUIET) + if os.getenv('WORKSPACE') == None: + print "ERROR: WORKSPACE should be specified or edksetup script should be executed before run TargetTool" + sys.exit(1) + + (opt, args) = MyOptionParser() + if len(args) != 1 or (args[0].lower() != 'print' and args[0].lower() != 'clean' and args[0].lower() != 'set'): + print "The number of args isn't 1 or the value of args is invalid." + sys.exit(1) + if opt.NUM != None and opt.NUM < 1: + print "The MAX_CONCURRENT_THREAD_NUMBER must be larger than 0." + sys.exit(1) + if opt.TARGET != None and len(opt.TARGET) > 1: + for elem in opt.TARGET: + if elem == '0': + print "0 will clear the TARGET setting in target.txt and can't combine with other value." + sys.exit(1) + if opt.TARGET_ARCH != None and len(opt.TARGET_ARCH) > 1: + for elem in opt.TARGET_ARCH: + if elem == '0': + print "0 will clear the TARGET_ARCH setting in target.txt and can't combine with other value." + sys.exit(1) + + try: + FileHandle = TargetTool(opt, args) + if FileHandle.Arg.lower() == 'print': + FileHandle.Print() + sys.exit(0) + elif FileHandle.Arg.lower() == 'clean': + FileHandle.RWFile('#', '=', 0) + else: + FileHandle.RWFile('#', '=', 1) + except Exception, e: + last_type, last_value, last_tb = sys.exc_info() + traceback.print_exception(last_type, last_value, last_tb) + diff --git a/BaseTools/Source/Python/TargetTool/__init__.py b/BaseTools/Source/Python/TargetTool/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/BaseTools/Source/Python/Trim/Trim.py b/BaseTools/Source/Python/Trim/Trim.py new file mode 100644 index 0000000000..a55c136edb --- /dev/null +++ b/BaseTools/Source/Python/Trim/Trim.py @@ -0,0 +1,520 @@ +## @file +# Trim files preprocessed by compiler +# +# Copyright (c) 2007, 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 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 re + +from optparse import OptionParser +from optparse import make_option +from Common.BuildToolError import * +from Common.Misc import * + +import Common.EdkLogger as EdkLogger + +# Version and Copyright +__version_number__ = "0.10" +__version__ = "%prog Version " + __version_number__ +__copyright__ = "Copyright (c) 2007-2008, Intel Corporation. All rights reserved." + +## Regular expression for matching Line Control directive like "#line xxx" +gLineControlDirective = re.compile('^\s*#(?:line)?\s+([0-9]+)\s+"*([^"]*)"') +## Regular expression for matching "typedef struct" +gTypedefPattern = re.compile("^\s*typedef\s+struct\s*[{]*$", re.MULTILINE) +## Regular expression for matching "#pragma pack" +gPragmaPattern = re.compile("^\s*#pragma\s+pack", re.MULTILINE) +## Regular expression for matching HEX number +gHexNumberPattern = re.compile("0[xX]([0-9a-fA-F]+)") +## Regular expression for matching "Include ()" in asl file +gAslIncludePattern = re.compile("^(\s*)[iI]nclude\s*\(\"?([^\"\(\)]+)\"\)", re.MULTILINE) +## Patterns used to convert EDK conventions to EDK2 ECP conventions +gImportCodePatterns = [ + [ + re.compile('^(\s*)\(\*\*PeiServices\)\.PciCfg\s*=\s*([^;\s]+);', re.MULTILINE), + '''\\1{ +\\1 STATIC EFI_PEI_PPI_DESCRIPTOR gEcpPeiPciCfgPpiList = { +\\1 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), +\\1 &gEcpPeiPciCfgPpiGuid, +\\1 \\2 +\\1 }; +\\1 (**PeiServices).InstallPpi (PeiServices, &gEcpPeiPciCfgPpiList); +\\1}''' + ], + + [ + re.compile('^(\s*)\(\*PeiServices\)->PciCfg\s*=\s*([^;\s]+);', re.MULTILINE), + '''\\1{ +\\1 STATIC EFI_PEI_PPI_DESCRIPTOR gEcpPeiPciCfgPpiList = { +\\1 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), +\\1 &gEcpPeiPciCfgPpiGuid, +\\1 \\2 +\\1 }; +\\1 (**PeiServices).InstallPpi (PeiServices, &gEcpPeiPciCfgPpiList); +\\1}''' + ], + + [ + re.compile("(\s*).+->Modify[\s\n]*\(", re.MULTILINE), + '\\1PeiLibPciCfgModify (' + ], + + [ + re.compile("(\W*)gRT->ReportStatusCode[\s\n]*\(", re.MULTILINE), + '\\1EfiLibReportStatusCode (' + ], + + [ + re.compile('#include\s+["<]LoadFile\.h[">]', re.MULTILINE), + '#include ' + ], + + [ + re.compile("(\s*)\S*CreateEvent\s*\([\s\n]*EFI_EVENT_SIGNAL_READY_TO_BOOT[^,]*,((?:[^;]+\n)+)(\s*\));", re.MULTILINE), + '\\1EfiCreateEventReadyToBoot (\\2\\3;' + ], + + [ + re.compile("(\s*)\S*CreateEvent\s*\([\s\n]*EFI_EVENT_SIGNAL_LEGACY_BOOT[^,]*,((?:[^;]+\n)+)(\s*\));", re.MULTILINE), + '\\1EfiCreateEventLegacyBoot (\\2\\3;' + ], +# [ +# re.compile("(\W)(PEI_PCI_CFG_PPI)(\W)", re.MULTILINE), +# '\\1ECP_\\2\\3' +# ] +] + +## file cache to avoid circular include in ASL file +gIncludedAslFile = [] + +## Trim preprocessed source code +# +# Remove extra content made by preprocessor. The preprocessor must enable the +# line number generation option when preprocessing. +# +# @param Source File to be trimmed +# @param Target File to store the trimmed content +# @param Convert If True, convert standard HEX format to MASM format +# +def TrimPreprocessedFile(Source, Target, Convert): + CreateDirectory(os.path.dirname(Target)) + try: + f = open (Source, 'r') + except: + EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Source) + + # read whole file + Lines = f.readlines() + f.close() + + PreprocessedFile = "" + InjectedFile = "" + LineIndexOfOriginalFile = None + NewLines = [] + LineControlDirectiveFound = False + for Index in range(len(Lines)): + Line = Lines[Index] + # + # Find out the name of files injected by preprocessor from the lines + # with Line Control directive + # + MatchList = gLineControlDirective.findall(Line) + if MatchList != []: + MatchList = MatchList[0] + if len(MatchList) == 2: + LineNumber = int(MatchList[0], 0) + InjectedFile = MatchList[1] + # The first injetcted file must be the preprocessed file itself + if PreprocessedFile == "": + PreprocessedFile = InjectedFile + LineControlDirectiveFound = True + continue + elif PreprocessedFile == "" or InjectedFile != PreprocessedFile: + continue + + if LineIndexOfOriginalFile == None: + # + # Any non-empty lines must be from original preprocessed file. + # And this must be the first one. + # + LineIndexOfOriginalFile = Index + EdkLogger.verbose("Found original file content starting from line %d" + % (LineIndexOfOriginalFile + 1)) + + # convert HEX number format if indicated + if Convert: + Line = gHexNumberPattern.sub(r"0\1h", Line) + + if LineNumber != None: + EdkLogger.verbose("Got line directive: line=%d" % LineNumber) + # in case preprocessor removed some lines, like blank or comment lines + if LineNumber <= len(NewLines): + # possible? + NewLines[LineNumber - 1] = Line + else: + if LineNumber > (len(NewLines) + 1): + for LineIndex in range(len(NewLines), LineNumber-1): + NewLines.append(os.linesep) + NewLines.append(Line) + LineNumber = None + EdkLogger.verbose("Now we have lines: %d" % len(NewLines)) + else: + NewLines.append(Line) + + # in case there's no line directive or linemarker found + if (not LineControlDirectiveFound) and NewLines == []: + NewLines = Lines + + # save to file + try: + f = open (Target, 'wb') + except: + EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Target) + f.writelines(NewLines) + f.close() + +## Trim preprocessed VFR file +# +# Remove extra content made by preprocessor. The preprocessor doesn't need to +# enable line number generation option when preprocessing. +# +# @param Source File to be trimmed +# @param Target File to store the trimmed content +# +def TrimPreprocessedVfr(Source, Target): + CreateDirectory(os.path.dirname(Target)) + + try: + f = open (Source,'r') + except: + EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Source) + # read whole file + Lines = f.readlines() + f.close() + + FoundTypedef = False + Brace = 0 + TypedefStart = 0 + TypedefEnd = 0 + for Index in range(len(Lines)): + Line = Lines[Index] + # don't trim the lines from "formset" definition to the end of file + if Line.strip() == 'formset': + break + + if FoundTypedef == False and (Line.find('#line') == 0 or Line.find('# ') == 0): + # empty the line number directive if it's not aomong "typedef struct" + Lines[Index] = "\n" + continue + + if FoundTypedef == False and gTypedefPattern.search(Line) == None: + # keep "#pragram pack" directive + if gPragmaPattern.search(Line) == None: + Lines[Index] = "\n" + continue + elif FoundTypedef == False: + # found "typedef struct", keept its position and set a flag + FoundTypedef = True + TypedefStart = Index + + # match { and } to find the end of typedef definition + if Line.find("{") >= 0: + Brace += 1 + elif Line.find("}") >= 0: + Brace -= 1 + + # "typedef struct" must end with a ";" + if Brace == 0 and Line.find(";") >= 0: + FoundTypedef = False + TypedefEnd = Index + # keep all "typedef struct" except to GUID, EFI_PLABEL and PAL_CALL_RETURN + if Line.strip("} ;\r\n") in ["GUID", "EFI_PLABEL", "PAL_CALL_RETURN"]: + for i in range(TypedefStart, TypedefEnd+1): + Lines[i] = "\n" + + # save all lines trimmed + try: + f = open (Target,'w') + except: + EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Target) + f.writelines(Lines) + f.close() + +## Read the content ASL file, including ASL included, recursively +# +# @param Source File to be read +# @param Indent Spaces before the Include() statement +# +def DoInclude(Source, Indent=''): + NewFileContent = [] + # avoid A "include" B and B "include" A + if Source in gIncludedAslFile: + EdkLogger.warn("Trim", "Circular include", + ExtraData= "%s -> %s" % (" -> ".join(gIncludedAslFile), Source)) + return [] + gIncludedAslFile.append(Source) + + try: + F = open(Source,'r') + except: + EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Source) + + for Line in F: + Result = gAslIncludePattern.findall(Line) + if len(Result) == 0: + NewFileContent.append("%s%s" % (Indent, Line)) + continue + CurrentIndent = Indent + Result[0][0] + IncludedFile = Result[0][1] + NewFileContent.extend(DoInclude(IncludedFile, CurrentIndent)) + + gIncludedAslFile.pop() + F.close() + + return NewFileContent + + +## Trim ASL file +# +# Replace ASL include statement with the content the included file +# +# @param Source File to be trimmed +# @param Target File to store the trimmed content +# +def TrimAslFile(Source, Target): + CreateDirectory(os.path.dirname(Target)) + + Cwd = os.getcwd() + SourceDir = os.path.dirname(Source) + if SourceDir == '': + SourceDir = '.' + os.chdir(SourceDir) + Lines = DoInclude(Source) + os.chdir(Cwd) + + # save all lines trimmed + try: + f = open (Target,'w') + except: + EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Target) + + f.writelines(Lines) + f.close() + +## Trim EDK source code file(s) +# +# +# @param Source File or directory to be trimmed +# @param Target File or directory to store the trimmed content +# +def TrimR8Sources(Source, Target): + if os.path.isdir(Source): + for CurrentDir, Dirs, Files in os.walk(Source): + if '.svn' in Dirs: + Dirs.remove('.svn') + elif "CVS" in Dirs: + Dirs.remove("CVS") + + for FileName in Files: + Dummy, Ext = os.path.splitext(FileName) + if Ext.upper() not in ['.C', '.H']: continue + if Target == None or Target == '': + TrimR8SourceCode( + os.path.join(CurrentDir, FileName), + os.path.join(CurrentDir, FileName) + ) + else: + TrimR8SourceCode( + os.path.join(CurrentDir, FileName), + os.path.join(Target, CurrentDir[len(Source)+1:], FileName) + ) + else: + TrimR8SourceCode(Source, Target) + +## Trim one EDK source code file +# +# Do following replacement: +# +# (**PeiServices\).PciCfg = <*>; +# => { +# STATIC EFI_PEI_PPI_DESCRIPTOR gEcpPeiPciCfgPpiList = { +# (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), +# &gEcpPeiPciCfgPpiGuid, +# <*> +# }; +# (**PeiServices).InstallPpi (PeiServices, &gEcpPeiPciCfgPpiList); +# +# <*>Modify(<*>) +# => PeiLibPciCfgModify (<*>) +# +# gRT->ReportStatusCode (<*>) +# => EfiLibReportStatusCode (<*>) +# +# #include +# => #include +# +# CreateEvent (EFI_EVENT_SIGNAL_READY_TO_BOOT, <*>) +# => EfiCreateEventReadyToBoot (<*>) +# +# CreateEvent (EFI_EVENT_SIGNAL_LEGACY_BOOT, <*>) +# => EfiCreateEventLegacyBoot (<*>) +# +# @param Source File to be trimmed +# @param Target File to store the trimmed content +# +def TrimR8SourceCode(Source, Target): + EdkLogger.verbose("\t%s -> %s" % (Source, Target)) + CreateDirectory(os.path.dirname(Target)) + + try: + f = open (Source,'rb') + except: + EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Source) + # read whole file + Lines = f.read() + f.close() + + NewLines = None + for Re,Repl in gImportCodePatterns: + if NewLines == None: + NewLines = Re.sub(Repl, Lines) + else: + NewLines = Re.sub(Repl, NewLines) + + # save all lines if trimmed + if Source == Target and NewLines == Lines: + return + + try: + f = open (Target,'wb') + except: + EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Target) + f.write(NewLines) + f.close() + + +## Parse command line options +# +# Using standard Python module optparse to parse command line option of this tool. +# +# @retval Options A optparse.Values object containing the parsed options +# @retval InputFile Path of file to be trimmed +# +def Options(): + OptionList = [ + make_option("-s", "--source-code", dest="FileType", const="SourceCode", action="store_const", + help="The input file is preprocessed source code, including C or assembly code"), + make_option("-r", "--vfr-file", dest="FileType", const="Vfr", action="store_const", + help="The input file is preprocessed VFR file"), + make_option("-a", "--asl-file", dest="FileType", const="Asl", action="store_const", + help="The input file is ASL file"), + make_option("-8", "--r8-source-code", dest="FileType", const="R8SourceCode", action="store_const", + help="The input file is source code for R8 to be trimmed for ECP"), + + make_option("-c", "--convert-hex", dest="ConvertHex", action="store_true", + help="Convert standard hex format (0xabcd) to MASM format (abcdh)"), + + make_option("-o", "--output", dest="OutputFile", + help="File to store the trimmed content"), + make_option("-v", "--verbose", dest="LogLevel", action="store_const", const=EdkLogger.VERBOSE, + help="Run verbosely"), + make_option("-d", "--debug", dest="LogLevel", type="int", + help="Run with debug information"), + make_option("-q", "--quiet", dest="LogLevel", action="store_const", const=EdkLogger.QUIET, + help="Run quietly"), + make_option("-?", action="help", help="show this help message and exit"), + ] + + # use clearer usage to override default usage message + UsageString = "%prog [-s|-r|-a] [-c] [-v|-d |-q] [-o ] " + + Parser = OptionParser(description=__copyright__, version=__version__, option_list=OptionList, usage=UsageString) + Parser.set_defaults(FileType="Vfr") + Parser.set_defaults(ConvertHex=False) + Parser.set_defaults(LogLevel=EdkLogger.INFO) + + Options, Args = Parser.parse_args() + + # error check + if len(Args) == 0: + EdkLogger.error("Trim", OPTION_MISSING, ExtraData=Parser.get_usage()) + if len(Args) > 1: + EdkLogger.error("Trim", OPTION_NOT_SUPPORTED, ExtraData=Parser.get_usage()) + + InputFile = Args[0] + return Options, InputFile + +## 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(): + try: + EdkLogger.Initialize() + CommandOptions, InputFile = Options() + if CommandOptions.LogLevel < EdkLogger.DEBUG_9: + EdkLogger.SetLevel(CommandOptions.LogLevel + 1) + else: + EdkLogger.SetLevel(CommandOptions.LogLevel) + except FatalError, X: + return 1 + + try: + if CommandOptions.FileType == "Vfr": + if CommandOptions.OutputFile == None: + CommandOptions.OutputFile = os.path.splitext(InputFile)[0] + '.iii' + TrimPreprocessedVfr(InputFile, CommandOptions.OutputFile) + elif CommandOptions.FileType == "Asl": + if CommandOptions.OutputFile == None: + CommandOptions.OutputFile = os.path.splitext(InputFile)[0] + '.iii' + TrimAslFile(InputFile, CommandOptions.OutputFile) + elif CommandOptions.FileType == "R8SourceCode": + TrimR8Sources(InputFile, CommandOptions.OutputFile) + else : + if CommandOptions.OutputFile == None: + CommandOptions.OutputFile = os.path.splitext(InputFile)[0] + '.iii' + TrimPreprocessedFile(InputFile, CommandOptions.OutputFile, CommandOptions.ConvertHex) + except FatalError, X: + import platform + import traceback + if CommandOptions != None and CommandOptions.LogLevel <= EdkLogger.DEBUG_9: + EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc()) + return 1 + except: + import traceback + import platform + EdkLogger.error( + "\nTrim", + CODE_ERROR, + "Unknown fatal error when trimming [%s]" % InputFile, + ExtraData="\n(Please send email to dev@buildtools.tianocore.org for help, attaching following call stack trace!)\n", + RaiseError=False + ) + EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc()) + return 1 + + return 0 + +if __name__ == '__main__': + r = Main() + ## 0-127 is a safe return range, and 1 is a standard default error + if r < 0 or r > 127: r = 1 + sys.exit(r) + diff --git a/BaseTools/Source/Python/Workspace/BuildClassObject.py b/BaseTools/Source/Python/Workspace/BuildClassObject.py new file mode 100644 index 0000000000..36c2ebf491 --- /dev/null +++ b/BaseTools/Source/Python/Workspace/BuildClassObject.py @@ -0,0 +1,364 @@ +## @file +# This file is used to define each component of the build database +# +# Copyright (c) 2007 ~ 2008, 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 accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# + +import os + +from Common.Misc import sdict +from Common.Misc import RealPath2 +from Common.BuildToolError import * + +## PcdClassObject +# +# This Class is used for PcdObject +# +# @param object: Inherited from object class +# @param Name: Input value for Name of Pcd, default is None +# @param Guid: Input value for Guid of Pcd, default is None +# @param Type: Input value for Type of Pcd, default is None +# @param DatumType: Input value for DatumType of Pcd, default is None +# @param Value: Input value for Value of Pcd, default is None +# @param Token: Input value for Token of Pcd, default is None +# @param MaxDatumSize: Input value for MaxDatumSize of Pcd, default is None +# @param SkuInfoList: Input value for SkuInfoList of Pcd, default is {} +# @param IsOverrided: Input value for IsOverrided of Pcd, default is False +# +# @var TokenCName: To store value for TokenCName +# @var TokenSpaceGuidCName: To store value for TokenSpaceGuidCName +# @var Type: To store value for Type +# @var DatumType: To store value for DatumType +# @var TokenValue: To store value for TokenValue +# @var MaxDatumSize: To store value for MaxDatumSize +# @var SkuInfoList: To store value for SkuInfoList +# @var IsOverrided: To store value for IsOverrided +# @var Phase: To store value for Phase, default is "DXE" +# +class PcdClassObject(object): + def __init__(self, Name = None, Guid = None, Type = None, DatumType = None, Value = None, Token = None, MaxDatumSize = None, SkuInfoList = {}, GuidValue = None): + self.TokenCName = Name + self.TokenSpaceGuidCName = Guid + self.TokenSpaceGuidValue = GuidValue + self.Type = Type + self.DatumType = DatumType + self.DefaultValue = Value + self.TokenValue = Token + self.MaxDatumSize = MaxDatumSize + self.SkuInfoList = SkuInfoList + self.Phase = "DXE" + self.Pending = False + + ## Convert the class to a string + # + # Convert each member of the class to string + # Organize to a signle line format string + # + # @retval Rtn Formatted String + # + def __str__(self): + Rtn = '\tTokenCName=' + str(self.TokenCName) + ', ' + \ + 'TokenSpaceGuidCName=' + str(self.TokenSpaceGuidCName) + ', ' + \ + 'Type=' + str(self.Type) + ', ' + \ + 'DatumType=' + str(self.DatumType) + ', ' + \ + 'DefaultValue=' + str(self.DefaultValue) + ', ' + \ + 'TokenValue=' + str(self.TokenValue) + ', ' + \ + 'MaxDatumSize=' + str(self.MaxDatumSize) + ', ' + for Item in self.SkuInfoList.values(): + Rtn = Rtn + 'SkuId=' + Item.SkuId + ', ' + 'SkuIdName=' + Item.SkuIdName + Rtn = Rtn + str(self.IsOverrided) + + return Rtn + + ## Override __eq__ function + # + # Check whether pcds are the same + # + # @retval False The two pcds are different + # @retval True The two pcds are the same + # + def __eq__(self, Other): + return Other and self.TokenCName == Other.TokenCName and self.TokenSpaceGuidCName == Other.TokenSpaceGuidCName + + ## Override __hash__ function + # + # Use (TokenCName, TokenSpaceGuidCName) as key in hash table + # + # @retval truple() Key for hash table + # + def __hash__(self): + return hash((self.TokenCName, self.TokenSpaceGuidCName)) + +## LibraryClassObject +# +# This Class defines LibraryClassObject used in BuildDatabase +# +# @param object: Inherited from object class +# @param Name: Input value for LibraryClassName, default is None +# @param SupModList: Input value for SupModList, default is [] +# @param Type: Input value for Type, default is None +# +# @var LibraryClass: To store value for LibraryClass +# @var SupModList: To store value for SupModList +# @var Type: To store value for Type +# +class LibraryClassObject(object): + def __init__(self, Name = None, SupModList = [], Type = None): + self.LibraryClass = Name + self.SupModList = SupModList + if Type != None: + self.SupModList = CleanString(Type).split(DataType.TAB_SPACE_SPLIT) + +## ModuleBuildClassObject +# +# This Class defines ModuleBuildClass +# +# @param object: Inherited from object class +# +# @var MetaFile: To store value for module meta file path +# @var BaseName: To store value for BaseName +# @var ModuleType: To store value for ModuleType +# @var Guid: To store value for Guid +# @var Version: To store value for Version +# @var PcdIsDriver: To store value for PcdIsDriver +# @var BinaryModule: To store value for BinaryModule +# @var CustomMakefile: To store value for CustomMakefile +# @var Specification: To store value for Specification +# @var Shadow To store value for Shadow +# @var LibraryClass: To store value for LibraryClass, it is a list structure as +# [ LibraryClassObject, ...] +# @var ModuleEntryPointList: To store value for ModuleEntryPointList +# @var ModuleUnloadImageList: To store value for ModuleUnloadImageList +# @var ConstructorList: To store value for ConstructorList +# @var DestructorList: To store value for DestructorList +# @var Binaries: To store value for Binaries, it is a list structure as +# [ ModuleBinaryClassObject, ...] +# @var Sources: To store value for Sources, it is a list structure as +# [ ModuleSourceFilesClassObject, ... ] +# @var LibraryClasses: To store value for LibraryClasses, it is a set structure as +# { [LibraryClassName, ModuleType] : LibraryClassInfFile } +# @var Protocols: To store value for Protocols, it is a list structure as +# [ ProtocolName, ... ] +# @var Ppis: To store value for Ppis, it is a list structure as +# [ PpiName, ... ] +# @var Guids: To store value for Guids, it is a list structure as +# [ GuidName, ... ] +# @var Includes: To store value for Includes, it is a list structure as +# [ IncludePath, ... ] +# @var Packages: To store value for Packages, it is a list structure as +# [ DecFileName, ... ] +# @var Pcds: To store value for Pcds, it is a set structure as +# { [(PcdCName, PcdGuidCName)] : PcdClassObject} +# @var BuildOptions: To store value for BuildOptions, it is a set structure as +# { [BuildOptionKey] : BuildOptionValue} +# @var Depex: To store value for Depex +# +class ModuleBuildClassObject(object): + def __init__(self): + self.AutoGenVersion = 0 + self.MetaFile = '' + self.BaseName = '' + self.ModuleType = '' + self.Guid = '' + self.Version = '' + self.PcdIsDriver = '' + self.BinaryModule = '' + self.Shadow = '' + self.SourceOverridePath = '' + self.CustomMakefile = {} + self.Specification = {} + self.LibraryClass = [] + self.ModuleEntryPointList = [] + self.ModuleUnloadImageList = [] + self.ConstructorList = [] + self.DestructorList = [] + + self.Binaries = [] + self.Sources = [] + self.LibraryClasses = sdict() + self.Libraries = [] + self.Protocols = [] + self.Ppis = [] + self.Guids = [] + self.Includes = [] + self.Packages = [] + self.Pcds = {} + self.BuildOptions = {} + self.Depex = {} + + ## Convert the class to a string + # + # Convert member MetaFile of the class to a string + # + # @retval string Formatted String + # + def __str__(self): + return str(self.MetaFile) + + ## Override __eq__ function + # + # Check whether ModuleBuildClassObjects are the same + # + # @retval False The two ModuleBuildClassObjects are different + # @retval True The two ModuleBuildClassObjects are the same + # + def __eq__(self, Other): + return self.MetaFile == Other + + ## Override __hash__ function + # + # Use MetaFile as key in hash table + # + # @retval string Key for hash table + # + def __hash__(self): + return hash(self.MetaFile) + +## PackageBuildClassObject +# +# This Class defines PackageBuildClass +# +# @param object: Inherited from object class +# +# @var MetaFile: To store value for package meta file path +# @var PackageName: To store value for PackageName +# @var Guid: To store value for Guid +# @var Version: To store value for Version +# @var Protocols: To store value for Protocols, it is a set structure as +# { [ProtocolName] : Protocol Guid, ... } +# @var Ppis: To store value for Ppis, it is a set structure as +# { [PpiName] : Ppi Guid, ... } +# @var Guids: To store value for Guids, it is a set structure as +# { [GuidName] : Guid, ... } +# @var Includes: To store value for Includes, it is a list structure as +# [ IncludePath, ... ] +# @var LibraryClasses: To store value for LibraryClasses, it is a set structure as +# { [LibraryClassName] : LibraryClassInfFile } +# @var Pcds: To store value for Pcds, it is a set structure as +# { [(PcdCName, PcdGuidCName)] : PcdClassObject} +# +class PackageBuildClassObject(object): + def __init__(self): + self.MetaFile = '' + self.PackageName = '' + self.Guid = '' + self.Version = '' + + self.Protocols = {} + self.Ppis = {} + self.Guids = {} + self.Includes = [] + self.LibraryClasses = {} + self.Pcds = {} + + ## Convert the class to a string + # + # Convert member MetaFile of the class to a string + # + # @retval string Formatted String + # + def __str__(self): + return str(self.MetaFile) + + ## Override __eq__ function + # + # Check whether PackageBuildClassObjects are the same + # + # @retval False The two PackageBuildClassObjects are different + # @retval True The two PackageBuildClassObjects are the same + # + def __eq__(self, Other): + return self.MetaFile == Other + + ## Override __hash__ function + # + # Use MetaFile as key in hash table + # + # @retval string Key for hash table + # + def __hash__(self): + return hash(self.MetaFile) + +## PlatformBuildClassObject +# +# This Class defines PlatformBuildClass +# +# @param object: Inherited from object class +# +# @var MetaFile: To store value for platform meta-file path +# @var PlatformName: To store value for PlatformName +# @var Guid: To store value for Guid +# @var Version: To store value for Version +# @var DscSpecification: To store value for DscSpecification +# @var OutputDirectory: To store value for OutputDirectory +# @var FlashDefinition: To store value for FlashDefinition +# @var BuildNumber: To store value for BuildNumber +# @var MakefileName: To store value for MakefileName +# @var SkuIds: To store value for SkuIds, it is a set structure as +# { 'SkuName' : SkuId, '!include' : includefilename, ...} +# @var Modules: To store value for Modules, it is a list structure as +# [ InfFileName, ... ] +# @var Libraries: To store value for Libraries, it is a list structure as +# [ InfFileName, ... ] +# @var LibraryClasses: To store value for LibraryClasses, it is a set structure as +# { (LibraryClassName, ModuleType) : LibraryClassInfFile } +# @var Pcds: To store value for Pcds, it is a set structure as +# { [(PcdCName, PcdGuidCName)] : PcdClassObject } +# @var BuildOptions: To store value for BuildOptions, it is a set structure as +# { [BuildOptionKey] : BuildOptionValue } +# +class PlatformBuildClassObject(object): + def __init__(self): + self.MetaFile = '' + self.PlatformName = '' + self.Guid = '' + self.Version = '' + self.DscSpecification = '' + self.OutputDirectory = '' + self.FlashDefinition = '' + self.BuildNumber = '' + self.MakefileName = '' + + self.SkuIds = {} + self.Modules = [] + self.LibraryInstances = [] + self.LibraryClasses = {} + self.Libraries = {} + self.Pcds = {} + self.BuildOptions = {} + + ## Convert the class to a string + # + # Convert member MetaFile of the class to a string + # + # @retval string Formatted String + # + def __str__(self): + return str(self.MetaFile) + + ## Override __eq__ function + # + # Check whether PlatformBuildClassObjects are the same + # + # @retval False The two PlatformBuildClassObjects are different + # @retval True The two PlatformBuildClassObjects are the same + # + def __eq__(self, Other): + return self.MetaFile == Other + + ## Override __hash__ function + # + # Use MetaFile as key in hash table + # + # @retval string Key for hash table + # + def __hash__(self): + return hash(self.MetaFile) + diff --git a/BaseTools/Source/Python/Workspace/MetaDataTable.py b/BaseTools/Source/Python/Workspace/MetaDataTable.py new file mode 100644 index 0000000000..c8166bfa90 --- /dev/null +++ b/BaseTools/Source/Python/Workspace/MetaDataTable.py @@ -0,0 +1,335 @@ +## @file +# This file is used to create/update/query/erase table for files +# +# Copyright (c) 2008, 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 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 Common.EdkLogger as EdkLogger +from CommonDataClass import DataClass +from CommonDataClass.DataClass import FileClass + +## Convert to SQL required string format +def ConvertToSqlString(StringList): + return map(lambda s: "'" + s.replace("'", "''") + "'", StringList) + +## TableFile +# +# This class defined a common table +# +# @param object: Inherited from object class +# +# @param Cursor: Cursor of the database +# @param TableName: Name of the table +# +class Table(object): + _COLUMN_ = '' + _ID_STEP_ = 1 + _ID_MAX_ = 0x80000000 + _DUMMY_ = 0 + + def __init__(self, Cursor, Name='', IdBase=0, Temporary=False): + self.Cur = Cursor + self.Table = Name + self.IdBase = int(IdBase) + self.ID = int(IdBase) + self.Temporary = Temporary + + def __str__(self): + return self.Table + + ## Create table + # + # Create a table + # + def Create(self, NewTable=True): + if NewTable: + self.Drop() + + if self.Temporary: + SqlCommand = """create temp table IF NOT EXISTS %s (%s)""" % (self.Table, self._COLUMN_) + else: + SqlCommand = """create table IF NOT EXISTS %s (%s)""" % (self.Table, self._COLUMN_) + EdkLogger.debug(EdkLogger.DEBUG_8, SqlCommand) + self.Cur.execute(SqlCommand) + self.ID = self.GetId() + + ## Insert table + # + # Insert a record into a table + # + def Insert(self, *Args): + self.ID = self.ID + self._ID_STEP_ + if self.ID >= (self.IdBase + self._ID_MAX_): + self.ID = self.IdBase + self._ID_STEP_ + Values = ", ".join([str(Arg) for Arg in Args]) + SqlCommand = "insert into %s values(%s, %s)" % (self.Table, self.ID, Values) + EdkLogger.debug(EdkLogger.DEBUG_5, SqlCommand) + self.Cur.execute(SqlCommand) + return self.ID + + ## Query table + # + # Query all records of the table + # + def Query(self): + SqlCommand = """select * from %s""" % self.Table + self.Cur.execute(SqlCommand) + for Rs in self.Cur: + EdkLogger.verbose(str(Rs)) + TotalCount = self.GetId() + + ## Drop a table + # + # Drop the table + # + def Drop(self): + SqlCommand = """drop table IF EXISTS %s""" % self.Table + self.Cur.execute(SqlCommand) + + ## Get count + # + # Get a count of all records of the table + # + # @retval Count: Total count of all records + # + def GetCount(self): + SqlCommand = """select count(ID) from %s""" % self.Table + Record = self.Cur.execute(SqlCommand).fetchall() + return Record[0][0] + + def GetId(self): + SqlCommand = """select max(ID) from %s""" % self.Table + Record = self.Cur.execute(SqlCommand).fetchall() + Id = Record[0][0] + if Id == None: + Id = self.IdBase + return Id + + ## Init the ID of the table + # + # Init the ID of the table + # + def InitID(self): + self.ID = self.GetId() + + ## Exec + # + # Exec Sql Command, return result + # + # @param SqlCommand: The SqlCommand to be executed + # + # @retval RecordSet: The result after executed + # + def Exec(self, SqlCommand): + EdkLogger.debug(EdkLogger.DEBUG_5, SqlCommand) + self.Cur.execute(SqlCommand) + RecordSet = self.Cur.fetchall() + return RecordSet + + def SetEndFlag(self): + self.Exec("insert into %s values(%s)" % (self.Table, self._DUMMY_)) + + def IsIntegral(self): + Result = self.Exec("select min(ID) from %s" % (self.Table)) + if Result[0][0] != -1: + return False + return True + +## TableFile +# +# This class defined a table used for file +# +# @param object: Inherited from object class +# +class TableFile(Table): + _COLUMN_ = ''' + ID INTEGER PRIMARY KEY, + Name VARCHAR NOT NULL, + ExtName VARCHAR, + Path VARCHAR, + FullPath VARCHAR NOT NULL, + Model INTEGER DEFAULT 0, + TimeStamp SINGLE NOT NULL + ''' + def __init__(self, Cursor): + Table.__init__(self, Cursor, 'File') + + ## Insert table + # + # Insert a record into table File + # + # @param Name: Name of a File + # @param ExtName: ExtName of a File + # @param Path: Path of a File + # @param FullPath: FullPath of a File + # @param Model: Model of a File + # @param TimeStamp: TimeStamp of a File + # + def Insert(self, Name, ExtName, Path, FullPath, Model, TimeStamp): + (Name, ExtName, Path, FullPath) = ConvertToSqlString((Name, ExtName, Path, FullPath)) + return Table.Insert( + self, + Name, + ExtName, + Path, + FullPath, + Model, + TimeStamp + ) + + ## InsertFile + # + # Insert one file to table + # + # @param FileFullPath: The full path of the file + # @param Model: The model of the file + # + # @retval FileID: The ID after record is inserted + # + def InsertFile(self, FileFullPath, Model): + (Filepath, Name) = os.path.split(FileFullPath) + (Root, Ext) = os.path.splitext(FileFullPath) + TimeStamp = os.stat(FileFullPath)[8] + File = FileClass(-1, Name, Ext, Filepath, FileFullPath, Model, '', [], [], []) + return self.Insert( + Name, + Ext, + Filepath, + FileFullPath, + Model, + TimeStamp + ) + + ## Get ID of a given file + # + # @param FilePath Path of file + # + # @retval ID ID value of given file in the table + # + def GetFileId(self, FilePath): + QueryScript = "select ID from %s where FullPath = '%s'" % (self.Table, FilePath) + RecordList = self.Exec(QueryScript) + if len(RecordList) == 0: + return None + return RecordList[0][0] + + ## Get type of a given file + # + # @param FileId ID of a file + # + # @retval file_type Model value of given file in the table + # + def GetFileType(self, FileId): + QueryScript = "select Model from %s where ID = '%s'" % (self.Table, FileId) + RecordList = self.Exec(QueryScript) + if len(RecordList) == 0: + return None + return RecordList[0][0] + + ## Get file timestamp of a given file + # + # @param FileId ID of file + # + # @retval timestamp TimeStamp value of given file in the table + # + def GetFileTimeStamp(self, FileId): + QueryScript = "select TimeStamp from %s where ID = '%s'" % (self.Table, FileId) + RecordList = self.Exec(QueryScript) + if len(RecordList) == 0: + return None + return RecordList[0][0] + + ## Update the timestamp of a given file + # + # @param FileId ID of file + # @param TimeStamp Time stamp of file + # + def SetFileTimeStamp(self, FileId, TimeStamp): + self.Exec("update %s set TimeStamp=%s where ID='%s'" % (self.Table, TimeStamp, FileId)) + + ## Get list of file with given type + # + # @param FileType Type value of file + # + # @retval file_list List of files with the given type + # + def GetFileList(self, FileType): + RecordList = self.Exec("select FullPath from %s where Model=%s" % (self.Table, FileType)) + if len(RecordList) == 0: + return [] + return [R[0] for R in RecordList] + +## TableDataModel +# +# This class defined a table used for data model +# +# @param object: Inherited from object class +# +# +class TableDataModel(Table): + _COLUMN_ = """ + ID INTEGER PRIMARY KEY, + CrossIndex INTEGER NOT NULL, + Name VARCHAR NOT NULL, + Description VARCHAR + """ + def __init__(self, Cursor): + Table.__init__(self, Cursor, 'DataModel') + + ## Insert table + # + # Insert a record into table DataModel + # + # @param ID: ID of a ModelType + # @param CrossIndex: CrossIndex of a ModelType + # @param Name: Name of a ModelType + # @param Description: Description of a ModelType + # + def Insert(self, CrossIndex, Name, Description): + (Name, Description) = ConvertToSqlString((Name, Description)) + return Table.Insert(self, CrossIndex, Name, Description) + + ## Init table + # + # Create all default records of table DataModel + # + def InitTable(self): + EdkLogger.verbose("\nInitialize table DataModel started ...") + Count = self.GetCount() + if Count != None and Count != 0: + return + for Item in DataClass.MODEL_LIST: + CrossIndex = Item[1] + Name = Item[0] + Description = Item[0] + self.Insert(CrossIndex, Name, Description) + EdkLogger.verbose("Initialize table DataModel ... DONE!") + + ## Get CrossIndex + # + # Get a model's cross index from its name + # + # @param ModelName: Name of the model + # @retval CrossIndex: CrossIndex of the model + # + def GetCrossIndex(self, ModelName): + CrossIndex = -1 + SqlCommand = """select CrossIndex from DataModel where name = '""" + ModelName + """'""" + self.Cur.execute(SqlCommand) + for Item in self.Cur: + CrossIndex = Item[0] + + return CrossIndex + diff --git a/BaseTools/Source/Python/Workspace/MetaFileParser.py b/BaseTools/Source/Python/Workspace/MetaFileParser.py new file mode 100644 index 0000000000..294237daee --- /dev/null +++ b/BaseTools/Source/Python/Workspace/MetaFileParser.py @@ -0,0 +1,1131 @@ +## @file +# This file is used to parse meta files +# +# Copyright (c) 2008, 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 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 time + +import Common.EdkLogger as EdkLogger +from CommonDataClass.DataClass import * +from Common.DataType import * +from Common.String import * +from Common.Misc import Blist, GuidStructureStringToGuidString, CheckPcdDatum + +## Base class of parser +# +# This class is used for derivation purpose. The specific parser for one kind +# type file must derive this class and implement some public interfaces. +# +# @param FilePath The path of platform description file +# @param FileType The raw data of DSC file +# @param Table Database used to retrieve module/package information +# @param Macros Macros used for replacement in file +# @param Owner Owner ID (for sub-section parsing) +# @param From ID from which the data comes (for !INCLUDE directive) +# +class MetaFileParser(object): + # data type (file content) for specific file type + DataType = {} + + ## Constructor of MetaFileParser + # + # Initialize object of MetaFileParser + # + # @param FilePath The path of platform description file + # @param FileType The raw data of DSC file + # @param Table Database used to retrieve module/package information + # @param Macros Macros used for replacement in file + # @param Owner Owner ID (for sub-section parsing) + # @param From ID from which the data comes (for !INCLUDE directive) + # + def __init__(self, FilePath, FileType, Table, Macros=None, Owner=-1, From=-1): + self._Table = Table + self._FileType = FileType + self.MetaFile = FilePath + self._FileDir = os.path.dirname(self.MetaFile) + self._Macros = {} + + # for recursive parsing + self._Owner = Owner + self._From = From + + # parsr status for parsing + self._Content = None + self._ValueList = ['', '', '', '', ''] + self._Scope = [] + self._LineIndex = 0 + self._CurrentLine = '' + self._SectionType = MODEL_UNKNOWN + self._SectionName = '' + self._InSubsection = False + self._SubsectionType = MODEL_UNKNOWN + self._SubsectionName = '' + self._LastItem = -1 + self._Enabled = 0 + self._Finished = False + + ## Store the parsed data in table + def _Store(self, *Args): + return self._Table.Insert(*Args) + + ## Virtual method for starting parse + def Start(self): + raise NotImplementedError + + ## Set parsing complete flag in both class and table + def _Done(self): + self._Finished = True + self._Table.SetEndFlag() + + ## Return the table containg parsed data + # + # If the parse complete flag is not set, this method will try to parse the + # file before return the table + # + def _GetTable(self): + if not self._Finished: + self.Start() + return self._Table + + ## Get the parse complete flag + def _GetFinished(self): + return self._Finished + + ## Set the complete flag + def _SetFinished(self, Value): + self._Finished = Value + + ## Use [] style to query data in table, just for readability + # + # DataInfo = [data_type, scope1(arch), scope2(platform,moduletype)] + # + def __getitem__(self, DataInfo): + if type(DataInfo) != type(()): + DataInfo = (DataInfo,) + return self.Table.Query(*DataInfo) + + ## Data parser for the common format in different type of file + # + # The common format in the meatfile is like + # + # xxx1 | xxx2 | xxx3 + # + def _CommonParser(self): + TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT) + self._ValueList[0:len(TokenList)] = TokenList + + ## Data parser for the format in which there's path + # + # Only path can have macro used. So we need to replace them before use. + # + def _PathParser(self): + TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT) + self._ValueList[0:len(TokenList)] = TokenList + if len(self._Macros) > 0: + for Index in range(0, len(self._ValueList)): + Value = self._ValueList[Index] + if Value == None or Value == '': + continue + self._ValueList[Index] = NormPath(Value, self._Macros) + + ## Skip unsupported data + def _Skip(self): + EdkLogger.warn("Parser", "Unrecognized content", File=self.MetaFile, + Line=self._LineIndex+1, ExtraData=self._CurrentLine); + self._ValueList[0:1] = [self._CurrentLine] + + ## Section header parser + # + # The section header is always in following format: + # + # [section_name.arch<.platform|module_type>] + # + def _SectionHeaderParser(self): + self._Scope = [] + self._SectionName = '' + ArchList = set() + for Item in GetSplitValueList(self._CurrentLine[1:-1], TAB_COMMA_SPLIT): + if Item == '': + continue + ItemList = GetSplitValueList(Item, TAB_SPLIT) + # different section should not mix in one section + if self._SectionName != '' and self._SectionName != ItemList[0].upper(): + EdkLogger.error('Parser', FORMAT_INVALID, "Different section names in the same section", + File=self.MetaFile, Line=self._LineIndex+1, ExtraData=self._CurrentLine) + self._SectionName = ItemList[0].upper() + if self._SectionName in self.DataType: + self._SectionType = self.DataType[self._SectionName] + else: + self._SectionType = MODEL_UNKNOWN + EdkLogger.warn("Parser", "Unrecognized section", File=self.MetaFile, + Line=self._LineIndex+1, ExtraData=self._CurrentLine) + # S1 is always Arch + if len(ItemList) > 1: + S1 = ItemList[1].upper() + else: + S1 = 'COMMON' + ArchList.add(S1) + # S2 may be Platform or ModuleType + if len(ItemList) > 2: + S2 = ItemList[2].upper() + else: + S2 = 'COMMON' + self._Scope.append([S1, S2]) + + # 'COMMON' must not be used with specific ARCHs at the same section + if 'COMMON' in ArchList and len(ArchList) > 1: + EdkLogger.error('Parser', FORMAT_INVALID, "'common' ARCH must not be used with specific ARCHs", + File=self.MetaFile, Line=self._LineIndex+1, ExtraData=self._CurrentLine) + + ## [defines] section parser + def _DefineParser(self): + TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1) + self._ValueList[0:len(TokenList)] = TokenList + if self._ValueList[1] == '': + EdkLogger.error('Parser', FORMAT_INVALID, "No value specified", + ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1) + + ## DEFINE name=value parser + def _MacroParser(self): + TokenList = GetSplitValueList(self._CurrentLine, ' ', 1) + MacroType = TokenList[0] + if len(TokenList) < 2 or TokenList[1] == '': + EdkLogger.error('Parser', FORMAT_INVALID, "No macro name/value given", + ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1) + TokenList = GetSplitValueList(TokenList[1], TAB_EQUAL_SPLIT, 1) + if TokenList[0] == '': + EdkLogger.error('Parser', FORMAT_INVALID, "No macro name given", + ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1) + if len(TokenList) == 1: + self._Macros[TokenList[0]] = '' + else: + # keep the macro definition for later use + self._Macros[TokenList[0]] = ReplaceMacro(TokenList[1], self._Macros, False) + + return TokenList[0], self._Macros[TokenList[0]] + + ## [BuildOptions] section parser + def _BuildOptionParser(self): + TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1) + TokenList2 = GetSplitValueList(TokenList[0], ':', 1) + if len(TokenList2) == 2: + self._ValueList[0] = TokenList2[0] # toolchain family + self._ValueList[1] = TokenList2[1] # keys + else: + self._ValueList[1] = TokenList[0] + if len(TokenList) == 2: # value + self._ValueList[2] = ReplaceMacro(TokenList[1], self._Macros) + + if self._ValueList[1].count('_') != 4: + EdkLogger.error( + 'Parser', + FORMAT_INVALID, + "'%s' must be in format of ____FLAGS" % self._ValueList[1], + ExtraData=self._CurrentLine, + File=self.MetaFile, + Line=self._LineIndex+1 + ) + + _SectionParser = {} + Table = property(_GetTable) + Finished = property(_GetFinished, _SetFinished) + + +## INF file parser class +# +# @param FilePath The path of platform description file +# @param FileType The raw data of DSC file +# @param Table Database used to retrieve module/package information +# @param Macros Macros used for replacement in file +# +class InfParser(MetaFileParser): + # INF file supported data types (one type per section) + DataType = { + TAB_UNKNOWN.upper() : MODEL_UNKNOWN, + TAB_INF_DEFINES.upper() : MODEL_META_DATA_HEADER, + TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION, + TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE, + TAB_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE, + TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS, + TAB_PACKAGES.upper() : MODEL_META_DATA_PACKAGE, + TAB_NMAKE.upper() : MODEL_META_DATA_NMAKE, + TAB_INF_FIXED_PCD.upper() : MODEL_PCD_FIXED_AT_BUILD, + TAB_INF_PATCH_PCD.upper() : MODEL_PCD_PATCHABLE_IN_MODULE, + TAB_INF_FEATURE_PCD.upper() : MODEL_PCD_FEATURE_FLAG, + TAB_INF_PCD_EX.upper() : MODEL_PCD_DYNAMIC_EX, + TAB_INF_PCD.upper() : MODEL_PCD_DYNAMIC, + TAB_SOURCES.upper() : MODEL_EFI_SOURCE_FILE, + TAB_GUIDS.upper() : MODEL_EFI_GUID, + TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL, + TAB_PPIS.upper() : MODEL_EFI_PPI, + TAB_DEPEX.upper() : MODEL_EFI_DEPEX, + TAB_BINARIES.upper() : MODEL_EFI_BINARY_FILE, + TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION + } + + ## Constructor of InfParser + # + # Initialize object of InfParser + # + # @param FilePath The path of module description file + # @param FileType The raw data of DSC file + # @param Table Database used to retrieve module/package information + # @param Macros Macros used for replacement in file + # + def __init__(self, FilePath, FileType, Table, Macros=None): + MetaFileParser.__init__(self, FilePath, FileType, Table, Macros) + + ## Parser starter + def Start(self): + NmakeLine = '' + try: + self._Content = open(self.MetaFile, 'r').readlines() + except: + EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile) + + # parse the file line by line + IsFindBlockComment = False + + for Index in range(0, len(self._Content)): + # skip empty, commented, block commented lines + Line = CleanString(self._Content[Index], AllowCppStyleComment=True) + NextLine = '' + if Index + 1 < len(self._Content): + NextLine = CleanString(self._Content[Index + 1]) + if Line == '': + continue + if Line.find(DataType.TAB_COMMENT_R8_START) > -1: + IsFindBlockComment = True + continue + if Line.find(DataType.TAB_COMMENT_R8_END) > -1: + IsFindBlockComment = False + continue + if IsFindBlockComment: + continue + + self._LineIndex = Index + self._CurrentLine = Line + + # section header + if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END: + self._SectionHeaderParser() + continue + # merge two lines specified by '\' in section NMAKE + elif self._SectionType == MODEL_META_DATA_NMAKE: + if Line[-1] == '\\': + if NextLine == '': + self._CurrentLine = NmakeLine + Line[0:-1] + NmakeLine = '' + else: + if NextLine[0] == TAB_SECTION_START and NextLine[-1] == TAB_SECTION_END: + self._CurrentLine = NmakeLine + Line[0:-1] + NmakeLine = '' + else: + NmakeLine = NmakeLine + ' ' + Line[0:-1] + continue + else: + self._CurrentLine = NmakeLine + Line + NmakeLine = '' + elif Line.upper().startswith('DEFINE '): + # file private macros + self._MacroParser() + continue + + # section content + self._ValueList = ['','',''] + # parse current line, result will be put in self._ValueList + self._SectionParser[self._SectionType](self) + if self._ValueList == None: + continue + # + # Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1, + # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1 + # + for Arch, Platform in self._Scope: + self._Store(self._SectionType, + self._ValueList[0], + self._ValueList[1], + self._ValueList[2], + Arch, + Platform, + self._Owner, + self._LineIndex+1, + -1, + self._LineIndex+1, + -1, + 0 + ) + self._Done() + + ## Data parser for the format in which there's path + # + # Only path can have macro used. So we need to replace them before use. + # + def _IncludeParser(self): + TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT) + self._ValueList[0:len(TokenList)] = TokenList + if len(self._Macros) > 0: + for Index in range(0, len(self._ValueList)): + Value = self._ValueList[Index] + if Value.upper().find('$(EFI_SOURCE)\Edk'.upper()) > -1 or Value.upper().find('$(EFI_SOURCE)/Edk'.upper()) > -1: + Value = '$(EDK_SOURCE)' + Value[17:] + if Value.find('$(EFI_SOURCE)') > -1 or Value.find('$(EDK_SOURCE)') > -1: + pass + elif Value.startswith('.'): + pass + elif Value.startswith('$('): + pass + else: + Value = '$(EFI_SOURCE)/' + Value + + if Value == None or Value == '': + continue + self._ValueList[Index] = NormPath(Value, self._Macros) + + ## Parse [Sources] section + # + # Only path can have macro used. So we need to replace them before use. + # + def _SourceFileParser(self): + TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT) + self._ValueList[0:len(TokenList)] = TokenList + # For Acpi tables, remove macro like ' TABLE_NAME=Sata1' + if 'COMPONENT_TYPE' in self._Macros: + if self._Macros['COMPONENT_TYPE'].upper() == 'ACPITABLE': + self._ValueList[0] = GetSplitValueList(self._ValueList[0], ' ', 1)[0] + if self._Macros['BASE_NAME'] == 'Microcode': + pass + if len(self._Macros) > 0: + for Index in range(0, len(self._ValueList)): + Value = self._ValueList[Index] + if Value == None or Value == '': + continue + self._ValueList[Index] = NormPath(Value, self._Macros) + + ## Parse [Binaries] section + # + # Only path can have macro used. So we need to replace them before use. + # + def _BinaryFileParser(self): + TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 2) + if len(TokenList) < 2: + EdkLogger.error('Parser', FORMAT_INVALID, "No file type or path specified", + ExtraData=self._CurrentLine + " ( | [| ])", + File=self.MetaFile, Line=self._LineIndex+1) + if not TokenList[0]: + EdkLogger.error('Parser', FORMAT_INVALID, "No file type specified", + ExtraData=self._CurrentLine + " ( | [| ])", + File=self.MetaFile, Line=self._LineIndex+1) + if not TokenList[1]: + EdkLogger.error('Parser', FORMAT_INVALID, "No file path specified", + ExtraData=self._CurrentLine + " ( | [| ])", + File=self.MetaFile, Line=self._LineIndex+1) + self._ValueList[0:len(TokenList)] = TokenList + self._ValueList[1] = NormPath(self._ValueList[1], self._Macros) + + ## [defines] section parser + def _DefineParser(self): + TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1) + self._ValueList[0:len(TokenList)] = TokenList + self._Macros[TokenList[0]] = ReplaceMacro(TokenList[1], self._Macros, False) + if self._ValueList[1] == '': + EdkLogger.error('Parser', FORMAT_INVALID, "No value specified", + ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1) + + ## [nmake] section parser (R8.x style only) + def _NmakeParser(self): + TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1) + self._ValueList[0:len(TokenList)] = TokenList + # remove macros + self._ValueList[1] = ReplaceMacro(self._ValueList[1], self._Macros, False) + # remove self-reference in macro setting + #self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''}) + + ## [FixedPcd], [FeaturePcd], [PatchPcd], [Pcd] and [PcdEx] sections parser + def _PcdParser(self): + TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1) + self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT) + if len(TokenList) > 1: + self._ValueList[2] = TokenList[1] + if self._ValueList[0] == '' or self._ValueList[1] == '': + EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified", + ExtraData=self._CurrentLine + " (.)", + File=self.MetaFile, Line=self._LineIndex+1) + + ## [depex] section parser + def _DepexParser(self): + self._ValueList[0:1] = [self._CurrentLine] + + _SectionParser = { + MODEL_UNKNOWN : MetaFileParser._Skip, + MODEL_META_DATA_HEADER : _DefineParser, + MODEL_META_DATA_BUILD_OPTION : MetaFileParser._BuildOptionParser, + MODEL_EFI_INCLUDE : _IncludeParser, # for R8.x modules + MODEL_EFI_LIBRARY_INSTANCE : MetaFileParser._CommonParser, # for R8.x modules + MODEL_EFI_LIBRARY_CLASS : MetaFileParser._PathParser, + MODEL_META_DATA_PACKAGE : MetaFileParser._PathParser, + MODEL_META_DATA_NMAKE : _NmakeParser, # for R8.x modules + MODEL_PCD_FIXED_AT_BUILD : _PcdParser, + MODEL_PCD_PATCHABLE_IN_MODULE : _PcdParser, + MODEL_PCD_FEATURE_FLAG : _PcdParser, + MODEL_PCD_DYNAMIC_EX : _PcdParser, + MODEL_PCD_DYNAMIC : _PcdParser, + MODEL_EFI_SOURCE_FILE : _SourceFileParser, + MODEL_EFI_GUID : MetaFileParser._CommonParser, + MODEL_EFI_PROTOCOL : MetaFileParser._CommonParser, + MODEL_EFI_PPI : MetaFileParser._CommonParser, + MODEL_EFI_DEPEX : _DepexParser, + MODEL_EFI_BINARY_FILE : _BinaryFileParser, + MODEL_META_DATA_USER_EXTENSION : MetaFileParser._Skip, + } + +## DSC file parser class +# +# @param FilePath The path of platform description file +# @param FileType The raw data of DSC file +# @param Table Database used to retrieve module/package information +# @param Macros Macros used for replacement in file +# @param Owner Owner ID (for sub-section parsing) +# @param From ID from which the data comes (for !INCLUDE directive) +# +class DscParser(MetaFileParser): + # DSC file supported data types (one type per section) + DataType = { + TAB_SKUIDS.upper() : MODEL_EFI_SKU_ID, + TAB_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE, + TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS, + TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION, + TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : MODEL_PCD_FIXED_AT_BUILD, + TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : MODEL_PCD_PATCHABLE_IN_MODULE, + TAB_PCDS_FEATURE_FLAG_NULL.upper() : MODEL_PCD_FEATURE_FLAG, + TAB_PCDS_DYNAMIC_DEFAULT_NULL.upper() : MODEL_PCD_DYNAMIC_DEFAULT, + TAB_PCDS_DYNAMIC_HII_NULL.upper() : MODEL_PCD_DYNAMIC_HII, + TAB_PCDS_DYNAMIC_VPD_NULL.upper() : MODEL_PCD_DYNAMIC_VPD, + TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL.upper() : MODEL_PCD_DYNAMIC_EX_DEFAULT, + TAB_PCDS_DYNAMIC_EX_HII_NULL.upper() : MODEL_PCD_DYNAMIC_EX_HII, + TAB_PCDS_DYNAMIC_EX_VPD_NULL.upper() : MODEL_PCD_DYNAMIC_EX_VPD, + TAB_COMPONENTS.upper() : MODEL_META_DATA_COMPONENT, + TAB_COMPONENTS_SOURCE_OVERRIDE_PATH.upper() : MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, + TAB_DSC_DEFINES.upper() : MODEL_META_DATA_HEADER, + TAB_INCLUDE.upper() : MODEL_META_DATA_INCLUDE, + TAB_IF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IF, + TAB_IF_DEF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF, + TAB_IF_N_DEF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF, + TAB_ELSE_IF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF, + TAB_ELSE.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE, + TAB_END_IF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF, + } + + # sections which allow "!include" directive + _IncludeAllowedSection = [ + TAB_LIBRARIES.upper(), + TAB_LIBRARY_CLASSES.upper(), + TAB_SKUIDS.upper(), + TAB_COMPONENTS.upper(), + TAB_BUILD_OPTIONS.upper(), + TAB_PCDS_FIXED_AT_BUILD_NULL.upper(), + TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper(), + TAB_PCDS_FEATURE_FLAG_NULL.upper(), + TAB_PCDS_DYNAMIC_DEFAULT_NULL.upper(), + TAB_PCDS_DYNAMIC_HII_NULL.upper(), + TAB_PCDS_DYNAMIC_VPD_NULL.upper(), + TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL.upper(), + TAB_PCDS_DYNAMIC_EX_HII_NULL.upper(), + TAB_PCDS_DYNAMIC_EX_VPD_NULL.upper(), + ] + + # operators which can be used in "!if/!ifdef/!ifndef" directives + _OP_ = { + "!" : lambda a: not a, + "!=" : lambda a,b: a!=b, + "==" : lambda a,b: a==b, + ">" : lambda a,b: a>b, + "<" : lambda a,b: a" : lambda a,b: a>=b, + ">=" : lambda a,b: a>=b, + "<=" : lambda a,b: a<=b, + "=<" : lambda a,b: a<=b, + } + + ## Constructor of DscParser + # + # Initialize object of DscParser + # + # @param FilePath The path of platform description file + # @param FileType The raw data of DSC file + # @param Table Database used to retrieve module/package information + # @param Macros Macros used for replacement in file + # @param Owner Owner ID (for sub-section parsing) + # @param From ID from which the data comes (for !INCLUDE directive) + # + def __init__(self, FilePath, FileType, Table, Macros=None, Owner=-1, From=-1): + MetaFileParser.__init__(self, FilePath, FileType, Table, Macros, Owner, From) + # to store conditional directive evaluation result + self._Eval = Blist() + + ## Parser starter + def Start(self): + try: + if self._Content == None: + self._Content = open(self.MetaFile, 'r').readlines() + except: + EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile) + + for Index in range(0, len(self._Content)): + Line = CleanString(self._Content[Index]) + # skip empty line + if Line == '': + continue + self._CurrentLine = Line + self._LineIndex = Index + + # section header + if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END: + self._SectionHeaderParser() + continue + # subsection ending + elif Line[0] == '}': + self._InSubsection = False + self._SubsectionType = MODEL_UNKNOWN + self._SubsectionName = '' + self._Owner = -1 + continue + # subsection header + elif Line[0] == TAB_OPTION_START and Line[-1] == TAB_OPTION_END: + self._SubsectionHeaderParser() + continue + # directive line + elif Line[0] == '!': + self._DirectiveParser() + continue + # file private macros + elif Line.upper().startswith('DEFINE '): + self._MacroParser() + continue + elif Line.upper().startswith('EDK_GLOBAL '): + (Name, Value) = self._MacroParser() + for Arch, ModuleType in self._Scope: + self._LastItem = self._Store( + MODEL_META_DATA_DEFINE, + Name, + Value, + '', + Arch, + 'COMMON', + self._Owner, + self._From, + self._LineIndex+1, + -1, + self._LineIndex+1, + -1, + self._Enabled + ) + continue + + # section content + if self._InSubsection: + SectionType = self._SubsectionType + SectionName = self._SubsectionName + if self._Owner == -1: + self._Owner = self._LastItem + else: + SectionType = self._SectionType + SectionName = self._SectionName + + self._ValueList = ['', '', ''] + self._SectionParser[SectionType](self) + if self._ValueList == None: + continue + + # + # Model, Value1, Value2, Value3, Arch, ModuleType, BelongsToItem=-1, BelongsToFile=-1, + # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1 + # + for Arch, ModuleType in self._Scope: + self._LastItem = self._Store( + SectionType, + self._ValueList[0], + self._ValueList[1], + self._ValueList[2], + Arch, + ModuleType, + self._Owner, + self._From, + self._LineIndex+1, + -1, + self._LineIndex+1, + -1, + self._Enabled + ) + self._Done() + + ## [defines] section parser + def _DefineParser(self): + TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1) + if len(TokenList) < 2: + EdkLogger.error('Parser', FORMAT_INVALID, "No value specified", + ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex+1) + # 'FLASH_DEFINITION', 'OUTPUT_DIRECTORY' need special processing + if TokenList[0] in ['FLASH_DEFINITION', 'OUTPUT_DIRECTORY']: + TokenList[1] = NormPath(TokenList[1], self._Macros) + self._ValueList[0:len(TokenList)] = TokenList + + ## parser + def _SubsectionHeaderParser(self): + self._SubsectionName = self._CurrentLine[1:-1].upper() + if self._SubsectionName in self.DataType: + self._SubsectionType = self.DataType[self._SubsectionName] + else: + self._SubsectionType = MODEL_UNKNOWN + EdkLogger.warn("Parser", "Unrecognized sub-section", File=self.MetaFile, + Line=self._LineIndex+1, ExtraData=self._CurrentLine) + + ## Directive statement parser + def _DirectiveParser(self): + self._ValueList = ['','',''] + TokenList = GetSplitValueList(self._CurrentLine, ' ', 1) + self._ValueList[0:len(TokenList)] = TokenList + DirectiveName = self._ValueList[0].upper() + if DirectiveName not in self.DataType: + EdkLogger.error("Parser", FORMAT_INVALID, "Unknown directive [%s]" % DirectiveName, + File=self.MetaFile, Line=self._LineIndex+1) + if DirectiveName in ['!IF', '!IFDEF', '!INCLUDE', '!IFNDEF', '!ELSEIF'] and self._ValueList[1] == '': + EdkLogger.error("Parser", FORMAT_INVALID, "Missing expression", + File=self.MetaFile, Line=self._LineIndex+1, + ExtraData=self._CurrentLine) + # keep the directive in database first + self._LastItem = self._Store( + self.DataType[DirectiveName], + self._ValueList[0], + self._ValueList[1], + self._ValueList[2], + 'COMMON', + 'COMMON', + self._Owner, + self._From, + self._LineIndex + 1, + -1, + self._LineIndex + 1, + -1, + 0 + ) + + # process the directive + if DirectiveName == "!INCLUDE": + if not self._SectionName in self._IncludeAllowedSection: + EdkLogger.error("Parser", FORMAT_INVALID, File=self.MetaFile, Line=self._LineIndex+1, + ExtraData="'!include' is not allowed under section [%s]" % self._SectionName) + # the included file must be relative to the parsing file + IncludedFile = os.path.join(self._FileDir, self._ValueList[1]) + Parser = DscParser(IncludedFile, self._FileType, self._Table, self._Macros, From=self._LastItem) + # set the parser status with current status + Parser._SectionName = self._SectionName + Parser._SectionType = self._SectionType + Parser._Scope = self._Scope + Parser._Enabled = self._Enabled + try: + Parser.Start() + except: + EdkLogger.error("Parser", PARSER_ERROR, File=self.MetaFile, Line=self._LineIndex+1, + ExtraData="Failed to parse content in file %s" % IncludedFile) + # update current status with sub-parser's status + self._SectionName = Parser._SectionName + self._SectionType = Parser._SectionType + self._Scope = Parser._Scope + self._Enabled = Parser._Enabled + else: + if DirectiveName in ["!IF", "!IFDEF", "!IFNDEF"]: + # evaluate the expression + Result = self._Evaluate(self._ValueList[1]) + if DirectiveName == "!IFNDEF": + Result = not Result + self._Eval.append(Result) + elif DirectiveName in ["!ELSEIF"]: + # evaluate the expression + self._Eval[-1] = (not self._Eval[-1]) & self._Evaluate(self._ValueList[1]) + elif DirectiveName in ["!ELSE"]: + self._Eval[-1] = not self._Eval[-1] + elif DirectiveName in ["!ENDIF"]: + if len(self._Eval) > 0: + self._Eval.pop() + else: + EdkLogger.error("Parser", FORMAT_INVALID, "!IF..[!ELSE]..!ENDIF doesn't match", + File=self.MetaFile, Line=self._LineIndex+1) + if self._Eval.Result == False: + self._Enabled = 0 - len(self._Eval) + else: + self._Enabled = len(self._Eval) + + ## Evaludate the value of expression in "if/ifdef/ifndef" directives + def _Evaluate(self, Expression): + TokenList = Expression.split() + TokenNumber = len(TokenList) + # one operand, guess it's just a macro name + if TokenNumber == 1: + return TokenList[0] in self._Macros + # two operands, suppose it's "!xxx" format + elif TokenNumber == 2: + Op = TokenList[0] + if Op not in self._OP_: + EdkLogger.error('Parser', FORMAT_INVALID, "Unsupported operator [%s]" % Op, File=self.MetaFile, + Line=self._LineIndex+1, ExtraData=Expression) + if TokenList[1].upper() == 'TRUE': + Value = True + else: + Value = False + return self._OP_[Op](Value) + # three operands + elif TokenNumber == 3: + Name = TokenList[0] + if Name not in self._Macros: + return False + Value = TokenList[2] + if Value[0] in ["'", '"'] and Value[-1] in ["'", '"']: + Value = Value[1:-1] + Op = TokenList[1] + if Op not in self._OP_: + EdkLogger.error('Parser', FORMAT_INVALID, "Unsupported operator [%s]" % Op, File=self.MetaFile, + Line=self._LineIndex+1, ExtraData=Expression) + return self._OP_[Op](self._Macros[Name], Value) + else: + EdkLogger.error('Parser', FORMAT_INVALID, File=self.MetaFile, Line=self._LineIndex+1, + ExtraData=Expression) + + ## PCD sections parser + # + # [PcdsFixedAtBuild] + # [PcdsPatchableInModule] + # [PcdsFeatureFlag] + # [PcdsDynamicEx + # [PcdsDynamicExDefault] + # [PcdsDynamicExVpd] + # [PcdsDynamicExHii] + # [PcdsDynamic] + # [PcdsDynamicDefault] + # [PcdsDynamicVpd] + # [PcdsDynamicHii] + # + def _PcdParser(self): + TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1) + self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT) + if len(TokenList) == 2: + self._ValueList[2] = TokenList[1] + if self._ValueList[0] == '' or self._ValueList[1] == '': + EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified", + ExtraData=self._CurrentLine + " (.|)", + File=self.MetaFile, Line=self._LineIndex+1) + if self._ValueList[2] == '': + EdkLogger.error('Parser', FORMAT_INVALID, "No PCD value given", + ExtraData=self._CurrentLine + " (.|)", + File=self.MetaFile, Line=self._LineIndex+1) + + ## [components] section parser + def _ComponentParser(self): + if self._CurrentLine[-1] == '{': + self._ValueList[0] = self._CurrentLine[0:-1].strip() + self._InSubsection = True + else: + self._ValueList[0] = self._CurrentLine + if len(self._Macros) > 0: + self._ValueList[0] = NormPath(self._ValueList[0], self._Macros) + + def _LibraryClassParser(self): + TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT) + if len(TokenList) < 2: + EdkLogger.error('Parser', FORMAT_INVALID, "No library class or instance specified", + ExtraData=self._CurrentLine + " (|)", + File=self.MetaFile, Line=self._LineIndex+1) + if TokenList[0] == '': + EdkLogger.error('Parser', FORMAT_INVALID, "No library class specified", + ExtraData=self._CurrentLine + " (|)", + File=self.MetaFile, Line=self._LineIndex+1) + if TokenList[1] == '': + EdkLogger.error('Parser', FORMAT_INVALID, "No library instance specified", + ExtraData=self._CurrentLine + " (|)", + File=self.MetaFile, Line=self._LineIndex+1) + self._ValueList[0:len(TokenList)] = TokenList + if len(self._Macros) > 0: + self._ValueList[1] = NormPath(self._ValueList[1], self._Macros) + + def _CompponentSourceOverridePathParser(self): + if len(self._Macros) > 0: + self._ValueList[0] = NormPath(self._CurrentLine, self._Macros) + + _SectionParser = { + MODEL_META_DATA_HEADER : _DefineParser, + MODEL_EFI_SKU_ID : MetaFileParser._CommonParser, + MODEL_EFI_LIBRARY_INSTANCE : MetaFileParser._PathParser, + MODEL_EFI_LIBRARY_CLASS : _LibraryClassParser, + MODEL_PCD_FIXED_AT_BUILD : _PcdParser, + MODEL_PCD_PATCHABLE_IN_MODULE : _PcdParser, + MODEL_PCD_FEATURE_FLAG : _PcdParser, + MODEL_PCD_DYNAMIC_DEFAULT : _PcdParser, + MODEL_PCD_DYNAMIC_HII : _PcdParser, + MODEL_PCD_DYNAMIC_VPD : _PcdParser, + MODEL_PCD_DYNAMIC_EX_DEFAULT : _PcdParser, + MODEL_PCD_DYNAMIC_EX_HII : _PcdParser, + MODEL_PCD_DYNAMIC_EX_VPD : _PcdParser, + MODEL_META_DATA_COMPONENT : _ComponentParser, + MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH : _CompponentSourceOverridePathParser, + MODEL_META_DATA_BUILD_OPTION : MetaFileParser._BuildOptionParser, + MODEL_UNKNOWN : MetaFileParser._Skip, + MODEL_META_DATA_USER_EXTENSION : MetaFileParser._Skip, + } + +## DEC file parser class +# +# @param FilePath The path of platform description file +# @param FileType The raw data of DSC file +# @param Table Database used to retrieve module/package information +# @param Macros Macros used for replacement in file +# +class DecParser(MetaFileParser): + # DEC file supported data types (one type per section) + DataType = { + TAB_DEC_DEFINES.upper() : MODEL_META_DATA_HEADER, + TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE, + TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS, + TAB_GUIDS.upper() : MODEL_EFI_GUID, + TAB_PPIS.upper() : MODEL_EFI_PPI, + TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL, + TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : MODEL_PCD_FIXED_AT_BUILD, + TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : MODEL_PCD_PATCHABLE_IN_MODULE, + TAB_PCDS_FEATURE_FLAG_NULL.upper() : MODEL_PCD_FEATURE_FLAG, + TAB_PCDS_DYNAMIC_NULL.upper() : MODEL_PCD_DYNAMIC, + TAB_PCDS_DYNAMIC_EX_NULL.upper() : MODEL_PCD_DYNAMIC_EX, + } + + ## Constructor of DecParser + # + # Initialize object of DecParser + # + # @param FilePath The path of platform description file + # @param FileType The raw data of DSC file + # @param Table Database used to retrieve module/package information + # @param Macros Macros used for replacement in file + # + def __init__(self, FilePath, FileType, Table, Macro=None): + MetaFileParser.__init__(self, FilePath, FileType, Table, Macro, -1) + + ## Parser starter + def Start(self): + try: + if self._Content == None: + self._Content = open(self.MetaFile, 'r').readlines() + except: + EdkLogger.error("Parser", FILE_READ_FAILURE, ExtraData=self.MetaFile) + + for Index in range(0, len(self._Content)): + Line = CleanString(self._Content[Index]) + # skip empty line + if Line == '': + continue + self._CurrentLine = Line + self._LineIndex = Index + + # section header + if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END: + self._SectionHeaderParser() + continue + elif Line.startswith('DEFINE '): + self._MacroParser() + continue + elif len(self._SectionType) == 0: + continue + + # section content + self._ValueList = ['','',''] + self._SectionParser[self._SectionType[0]](self) + if self._ValueList == None: + continue + + # + # Model, Value1, Value2, Value3, Arch, BelongsToItem=-1, LineBegin=-1, + # ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, FeatureFlag='', Enabled=-1 + # + for Arch, ModuleType, Type in self._Scope: + self._LastItem = self._Store( + Type, + self._ValueList[0], + self._ValueList[1], + self._ValueList[2], + Arch, + ModuleType, + self._Owner, + self._LineIndex+1, + -1, + self._LineIndex+1, + -1, + 0 + ) + self._Done() + + ## Section header parser + # + # The section header is always in following format: + # + # [section_name.arch<.platform|module_type>] + # + def _SectionHeaderParser(self): + self._Scope = [] + self._SectionName = '' + self._SectionType = [] + ArchList = set() + for Item in GetSplitValueList(self._CurrentLine[1:-1], TAB_COMMA_SPLIT): + if Item == '': + continue + ItemList = GetSplitValueList(Item, TAB_SPLIT) + + # different types of PCD are permissible in one section + self._SectionName = ItemList[0].upper() + if self._SectionName in self.DataType: + if self.DataType[self._SectionName] not in self._SectionType: + self._SectionType.append(self.DataType[self._SectionName]) + else: + EdkLogger.warn("Parser", "Unrecognized section", File=self.MetaFile, + Line=self._LineIndex+1, ExtraData=self._CurrentLine) + continue + + if MODEL_PCD_FEATURE_FLAG in self._SectionType and len(self._SectionType) > 1: + EdkLogger.error( + 'Parser', + FORMAT_INVALID, + "%s must not be in the same section of other types of PCD" % TAB_PCDS_FEATURE_FLAG_NULL, + File=self.MetaFile, + Line=self._LineIndex+1, + ExtraData=self._CurrentLine + ) + # S1 is always Arch + if len(ItemList) > 1: + S1 = ItemList[1].upper() + else: + S1 = 'COMMON' + ArchList.add(S1) + # S2 may be Platform or ModuleType + if len(ItemList) > 2: + S2 = ItemList[2].upper() + else: + S2 = 'COMMON' + if [S1, S2, self.DataType[self._SectionName]] not in self._Scope: + self._Scope.append([S1, S2, self.DataType[self._SectionName]]) + + # 'COMMON' must not be used with specific ARCHs at the same section + if 'COMMON' in ArchList and len(ArchList) > 1: + EdkLogger.error('Parser', FORMAT_INVALID, "'common' ARCH must not be used with specific ARCHs", + File=self.MetaFile, Line=self._LineIndex+1, ExtraData=self._CurrentLine) + + ## [guids], [ppis] and [protocols] section parser + def _GuidParser(self): + TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1) + if len(TokenList) < 2: + EdkLogger.error('Parser', FORMAT_INVALID, "No GUID name or value specified", + ExtraData=self._CurrentLine + " ( = )", + File=self.MetaFile, Line=self._LineIndex+1) + if TokenList[0] == '': + EdkLogger.error('Parser', FORMAT_INVALID, "No GUID name specified", + ExtraData=self._CurrentLine + " ( = )", + File=self.MetaFile, Line=self._LineIndex+1) + if TokenList[1] == '': + EdkLogger.error('Parser', FORMAT_INVALID, "No GUID value specified", + ExtraData=self._CurrentLine + " ( = )", + File=self.MetaFile, Line=self._LineIndex+1) + if TokenList[1][0] != '{' or TokenList[1][-1] != '}' or GuidStructureStringToGuidString(TokenList[1]) == '': + EdkLogger.error('Parser', FORMAT_INVALID, "Invalid GUID value format", + ExtraData=self._CurrentLine + \ + " ( = )", + File=self.MetaFile, Line=self._LineIndex+1) + self._ValueList[0] = TokenList[0] + self._ValueList[1] = TokenList[1] + + ## PCD sections parser + # + # [PcdsFixedAtBuild] + # [PcdsPatchableInModule] + # [PcdsFeatureFlag] + # [PcdsDynamicEx + # [PcdsDynamic] + # + def _PcdParser(self): + TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1) + self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT) + # check PCD information + if self._ValueList[0] == '' or self._ValueList[1] == '': + EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified", + ExtraData=self._CurrentLine + \ + " (.|||)", + File=self.MetaFile, Line=self._LineIndex+1) + # check PCD datum information + if len(TokenList) < 2 or TokenList[1] == '': + EdkLogger.error('Parser', FORMAT_INVALID, "No PCD Datum information given", + ExtraData=self._CurrentLine + \ + " (.|||)", + File=self.MetaFile, Line=self._LineIndex+1) + + ValueList = GetSplitValueList(TokenList[1]) + # check if there's enough datum information given + if len(ValueList) != 3: + EdkLogger.error('Parser', FORMAT_INVALID, "Invalid PCD Datum information given", + ExtraData=self._CurrentLine + \ + " (.|||)", + File=self.MetaFile, Line=self._LineIndex+1) + # check default value + if ValueList[0] == '': + EdkLogger.error('Parser', FORMAT_INVALID, "Missing DefaultValue in PCD Datum information", + ExtraData=self._CurrentLine + \ + " (.|||)", + File=self.MetaFile, Line=self._LineIndex+1) + # check datum type + if ValueList[1] == '': + EdkLogger.error('Parser', FORMAT_INVALID, "Missing DatumType in PCD Datum information", + ExtraData=self._CurrentLine + \ + " (.|||)", + File=self.MetaFile, Line=self._LineIndex+1) + # check token of the PCD + if ValueList[2] == '': + EdkLogger.error('Parser', FORMAT_INVALID, "Missing Token in PCD Datum information", + ExtraData=self._CurrentLine + \ + " (.|||)", + File=self.MetaFile, Line=self._LineIndex+1) + # check format of default value against the datum type + IsValid, Cause = CheckPcdDatum(ValueList[1], ValueList[0]) + if not IsValid: + EdkLogger.error('Parser', FORMAT_INVALID, Cause, ExtraData=self._CurrentLine, + File=self.MetaFile, Line=self._LineIndex+1) + self._ValueList[2] = TokenList[1] + + _SectionParser = { + MODEL_META_DATA_HEADER : MetaFileParser._DefineParser, + MODEL_EFI_INCLUDE : MetaFileParser._PathParser, + MODEL_EFI_LIBRARY_CLASS : MetaFileParser._PathParser, + MODEL_EFI_GUID : _GuidParser, + MODEL_EFI_PPI : _GuidParser, + MODEL_EFI_PROTOCOL : _GuidParser, + MODEL_PCD_FIXED_AT_BUILD : _PcdParser, + MODEL_PCD_PATCHABLE_IN_MODULE : _PcdParser, + MODEL_PCD_FEATURE_FLAG : _PcdParser, + MODEL_PCD_DYNAMIC : _PcdParser, + MODEL_PCD_DYNAMIC_EX : _PcdParser, + MODEL_UNKNOWN : MetaFileParser._Skip, + MODEL_META_DATA_USER_EXTENSION : MetaFileParser._Skip, + } + +## +# +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +# +if __name__ == '__main__': + pass + diff --git a/BaseTools/Source/Python/Workspace/MetaFileTable.py b/BaseTools/Source/Python/Workspace/MetaFileTable.py new file mode 100644 index 0000000000..22e2afa4c9 --- /dev/null +++ b/BaseTools/Source/Python/Workspace/MetaFileTable.py @@ -0,0 +1,275 @@ +## @file +# This file is used to create/update/query/erase a meta file table +# +# Copyright (c) 2008, 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 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 Common.EdkLogger as EdkLogger +from MetaDataTable import Table +from MetaDataTable import ConvertToSqlString + +## Python class representation of table storing module data +class ModuleTable(Table): + # TRICK: use file ID as the part before '.' + _ID_STEP_ = 0.00000001 + _ID_MAX_ = 0.99999999 + _COLUMN_ = ''' + ID REAL PRIMARY KEY, + Model INTEGER NOT NULL, + Value1 TEXT NOT NULL, + Value2 TEXT, + Value3 TEXT, + Scope1 TEXT, + Scope2 TEXT, + BelongsToItem REAL NOT NULL, + StartLine INTEGER NOT NULL, + StartColumn INTEGER NOT NULL, + EndLine INTEGER NOT NULL, + EndColumn INTEGER NOT NULL, + Enabled INTEGER DEFAULT 0 + ''' + # used as table end flag, in case the changes to database is not committed to db file + _DUMMY_ = "-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1" + + ## Constructor + def __init__(self, Cursor, Name='Inf', IdBase=0, Temporary=False): + Table.__init__(self, Cursor, Name, IdBase, Temporary) + + ## Insert a record into table Inf + # + # @param Model: Model of a Inf item + # @param Value1: Value1 of a Inf item + # @param Value2: Value2 of a Inf item + # @param Value3: Value3 of a Inf item + # @param Scope1: Arch of a Inf item + # @param Scope2 Platform os a Inf item + # @param BelongsToItem: The item belongs to which another item + # @param StartLine: StartLine of a Inf item + # @param StartColumn: StartColumn of a Inf item + # @param EndLine: EndLine of a Inf item + # @param EndColumn: EndColumn of a Inf item + # @param Enabled: If this item enabled + # + def Insert(self, Model, Value1, Value2, Value3, Scope1='COMMON', Scope2='COMMON', + BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0): + (Value1, Value2, Value3, Scope1, Scope2) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2)) + return Table.Insert( + self, + Model, + Value1, + Value2, + Value3, + Scope1, + Scope2, + BelongsToItem, + StartLine, + StartColumn, + EndLine, + EndColumn, + Enabled + ) + + ## Query table + # + # @param Model: The Model of Record + # @param Arch: The Arch attribute of Record + # @param Platform The Platform attribute of Record + # + # @retval: A recordSet of all found records + # + def Query(self, Model, Arch=None, Platform=None): + ConditionString = "Model=%s AND Enabled>=0" % Model + ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine" + + if Arch != None and Arch != 'COMMON': + ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Arch + if Platform != None and Platform != 'COMMON': + ConditionString += " AND (Scope2='%s' OR Scope2='COMMON' OR Scope2='DEFAULT')" % Platform + + SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString) + return self.Exec(SqlCommand) + +## Python class representation of table storing package data +class PackageTable(Table): + _ID_STEP_ = 0.00000001 + _ID_MAX_ = 0.99999999 + _COLUMN_ = ''' + ID REAL PRIMARY KEY, + Model INTEGER NOT NULL, + Value1 TEXT NOT NULL, + Value2 TEXT, + Value3 TEXT, + Scope1 TEXT, + Scope2 TEXT, + BelongsToItem REAL NOT NULL, + StartLine INTEGER NOT NULL, + StartColumn INTEGER NOT NULL, + EndLine INTEGER NOT NULL, + EndColumn INTEGER NOT NULL, + Enabled INTEGER DEFAULT 0 + ''' + # used as table end flag, in case the changes to database is not committed to db file + _DUMMY_ = "-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1" + + ## Constructor + def __init__(self, Cursor, Name='Dec', IdBase=0, Temporary=False): + Table.__init__(self, Cursor, Name, IdBase, Temporary) + + ## Insert table + # + # Insert a record into table Dec + # + # @param Model: Model of a Dec item + # @param Value1: Value1 of a Dec item + # @param Value2: Value2 of a Dec item + # @param Value3: Value3 of a Dec item + # @param Scope1: Arch of a Dec item + # @param Scope2: Module type of a Dec item + # @param BelongsToItem: The item belongs to which another item + # @param StartLine: StartLine of a Dec item + # @param StartColumn: StartColumn of a Dec item + # @param EndLine: EndLine of a Dec item + # @param EndColumn: EndColumn of a Dec item + # @param Enabled: If this item enabled + # + def Insert(self, Model, Value1, Value2, Value3, Scope1='COMMON', Scope2='COMMON', + BelongsToItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=0): + (Value1, Value2, Value3, Scope1, Scope2) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2)) + return Table.Insert( + self, + Model, + Value1, + Value2, + Value3, + Scope1, + Scope2, + BelongsToItem, + StartLine, + StartColumn, + EndLine, + EndColumn, + Enabled + ) + + ## Query table + # + # @param Model: The Model of Record + # @param Arch: The Arch attribute of Record + # + # @retval: A recordSet of all found records + # + def Query(self, Model, Arch=None): + ConditionString = "Model=%s AND Enabled>=0" % Model + ValueString = "Value1,Value2,Value3,Scope1,ID,StartLine" + + if Arch != None and Arch != 'COMMON': + ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Arch + + SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString) + return self.Exec(SqlCommand) + +## Python class representation of table storing platform data +class PlatformTable(Table): + _ID_STEP_ = 0.00000001 + _ID_MAX_ = 0.99999999 + _COLUMN_ = ''' + ID REAL PRIMARY KEY, + Model INTEGER NOT NULL, + Value1 TEXT NOT NULL, + Value2 TEXT, + Value3 TEXT, + Scope1 TEXT, + Scope2 TEXT, + BelongsToItem REAL NOT NULL, + FromItem REAL NOT NULL, + StartLine INTEGER NOT NULL, + StartColumn INTEGER NOT NULL, + EndLine INTEGER NOT NULL, + EndColumn INTEGER NOT NULL, + Enabled INTEGER DEFAULT 0 + ''' + # used as table end flag, in case the changes to database is not committed to db file + _DUMMY_ = "-1, -1, '====', '====', '====', '====', '====', -1, -1, -1, -1, -1, -1, -1" + + ## Constructor + def __init__(self, Cursor, Name='Dsc', IdBase=0, Temporary=False): + Table.__init__(self, Cursor, Name, IdBase, Temporary) + + ## Insert table + # + # Insert a record into table Dsc + # + # @param Model: Model of a Dsc item + # @param Value1: Value1 of a Dsc item + # @param Value2: Value2 of a Dsc item + # @param Value3: Value3 of a Dsc item + # @param Scope1: Arch of a Dsc item + # @param Scope2: Module type of a Dsc item + # @param BelongsToItem: The item belongs to which another item + # @param FromItem: The item belongs to which dsc file + # @param StartLine: StartLine of a Dsc item + # @param StartColumn: StartColumn of a Dsc item + # @param EndLine: EndLine of a Dsc item + # @param EndColumn: EndColumn of a Dsc item + # @param Enabled: If this item enabled + # + def Insert(self, Model, Value1, Value2, Value3, Scope1='COMMON', Scope2='COMMON', BelongsToItem=-1, + FromItem=-1, StartLine=-1, StartColumn=-1, EndLine=-1, EndColumn=-1, Enabled=1): + (Value1, Value2, Value3, Scope1, Scope2) = ConvertToSqlString((Value1, Value2, Value3, Scope1, Scope2)) + return Table.Insert( + self, + Model, + Value1, + Value2, + Value3, + Scope1, + Scope2, + BelongsToItem, + FromItem, + StartLine, + StartColumn, + EndLine, + EndColumn, + Enabled + ) + + ## Query table + # + # @param Model: The Model of Record + # @param Scope1: Arch of a Dsc item + # @param Scope2: Module type of a Dsc item + # @param BelongsToItem: The item belongs to which another item + # @param FromItem: The item belongs to which dsc file + # + # @retval: A recordSet of all found records + # + def Query(self, Model, Scope1=None, Scope2=None, BelongsToItem=None, FromItem=None): + ConditionString = "Model=%s AND Enabled>=0" % Model + ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine" + + if Scope1 != None and Scope1 != 'COMMON': + ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Scope1 + if Scope2 != None and Scope2 != 'COMMON': + ConditionString += " AND (Scope2='%s' OR Scope2='COMMON' OR Scope2='DEFAULT')" % Scope2 + + if BelongsToItem != None: + ConditionString += " AND BelongsToItem=%s" % BelongsToItem + else: + ConditionString += " AND BelongsToItem<0" + + if FromItem != None: + ConditionString += " AND FromItem=%s" % FromItem + + SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString) + return self.Exec(SqlCommand) + diff --git a/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py new file mode 100644 index 0000000000..8f0056e197 --- /dev/null +++ b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py @@ -0,0 +1,2274 @@ +## @file +# This file is used to create a database used by build tool +# +# Copyright (c) 2008, 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 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 os.path + +import Common.EdkLogger as EdkLogger +import Common.GlobalData as GlobalData + +from Common.String import * +from Common.DataType import * +from Common.Misc import * + +from CommonDataClass.CommonClass import SkuInfoClass + +from MetaDataTable import * +from MetaFileTable import * +from MetaFileParser import * +from BuildClassObject import * + +## Platform build information from DSC file +# +# This class is used to retrieve information stored in database and convert them +# into PlatformBuildClassObject form for easier use for AutoGen. +# +class DscBuildData(PlatformBuildClassObject): + # dict used to convert PCD type in database to string used by build tool + _PCD_TYPE_STRING_ = { + MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild", + MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule", + MODEL_PCD_FEATURE_FLAG : "FeatureFlag", + MODEL_PCD_DYNAMIC : "Dynamic", + MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic", + MODEL_PCD_DYNAMIC_HII : "DynamicHii", + MODEL_PCD_DYNAMIC_VPD : "DynamicVpd", + MODEL_PCD_DYNAMIC_EX : "DynamicEx", + MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx", + MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii", + MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd", + } + + # dict used to convert part of [Defines] to members of DscBuildData directly + _PROPERTY_ = { + # + # Required Fields + # + TAB_DSC_DEFINES_PLATFORM_NAME : "_PlatformName", + TAB_DSC_DEFINES_PLATFORM_GUID : "_Guid", + TAB_DSC_DEFINES_PLATFORM_VERSION : "_Version", + TAB_DSC_DEFINES_DSC_SPECIFICATION : "_DscSpecification", + #TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory", + #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList", + #TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets", + #TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName", + #TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition", + TAB_DSC_DEFINES_BUILD_NUMBER : "_BuildNumber", + TAB_DSC_DEFINES_MAKEFILE_NAME : "_MakefileName", + TAB_DSC_DEFINES_BS_BASE_ADDRESS : "_BsBaseAddress", + TAB_DSC_DEFINES_RT_BASE_ADDRESS : "_RtBaseAddress", + } + + # used to compose dummy library class name for those forced library instances + _NullLibraryNumber = 0 + + ## Constructor of DscBuildData + # + # Initialize object of DscBuildData + # + # @param FilePath The path of platform description file + # @param RawData The raw data of DSC file + # @param BuildDataBase Database used to retrieve module/package information + # @param Arch The target architecture + # @param Platform (not used for DscBuildData) + # @param Macros Macros used for replacement in DSC file + # + def __init__(self, FilePath, RawData, BuildDataBase, Arch='COMMON', Platform='DUMMY', Macros={}): + self.MetaFile = FilePath + self._RawData = RawData + self._Bdb = BuildDataBase + self._Arch = Arch + self._Macros = Macros + self._Clear() + RecordList = self._RawData[MODEL_META_DATA_DEFINE, self._Arch] + for Record in RecordList: + GlobalData.gEdkGlobal[Record[0]] = Record[1] + + ## XXX[key] = value + def __setitem__(self, key, value): + self.__dict__[self._PROPERTY_[key]] = value + + ## value = XXX[key] + def __getitem__(self, key): + return self.__dict__[self._PROPERTY_[key]] + + ## "in" test support + def __contains__(self, key): + return key in self._PROPERTY_ + + ## Set all internal used members of DscBuildData to None + def _Clear(self): + self._Header = None + self._PlatformName = None + self._Guid = None + self._Version = None + self._DscSpecification = None + self._OutputDirectory = None + self._SupArchList = None + self._BuildTargets = None + self._SkuName = None + self._FlashDefinition = None + self._BuildNumber = None + self._MakefileName = None + self._BsBaseAddress = None + self._RtBaseAddress = None + self._SkuIds = None + self._Modules = None + self._LibraryInstances = None + self._LibraryClasses = None + self._Pcds = None + self._BuildOptions = None + + ## Get architecture + def _GetArch(self): + return self._Arch + + ## Set architecture + # + # Changing the default ARCH to another may affect all other information + # because all information in a platform may be ARCH-related. That's + # why we need to clear all internal used members, in order to cause all + # information to be re-retrieved. + # + # @param Value The value of ARCH + # + def _SetArch(self, Value): + if self._Arch == Value: + return + self._Arch = Value + self._Clear() + + ## Retrieve all information in [Defines] section + # + # (Retriving all [Defines] information in one-shot is just to save time.) + # + def _GetHeaderInfo(self): + RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch] + for Record in RecordList: + Name = Record[0] + # items defined _PROPERTY_ don't need additional processing + if Name in self: + self[Name] = Record[1] + # some special items in [Defines] section need special treatment + elif Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY: + self._OutputDirectory = NormPath(Record[1], self._Macros) + if ' ' in self._OutputDirectory: + EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in OUTPUT_DIRECTORY", + File=self.MetaFile, Line=Record[-1], + ExtraData=self._OutputDirectory) + elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION: + self._FlashDefinition = PathClass(NormPath(Record[1], self._Macros), GlobalData.gWorkspace) + ErrorCode, ErrorInfo = self._FlashDefinition.Validate('.fdf') + if ErrorCode != 0: + EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1], + ExtraData=ErrorInfo) + elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES: + self._SupArchList = GetSplitValueList(Record[1], TAB_VALUE_SPLIT) + elif Name == TAB_DSC_DEFINES_BUILD_TARGETS: + self._BuildTargets = GetSplitValueList(Record[1]) + elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER: + if self._SkuName == None: + self._SkuName = Record[1] + # set _Header to non-None in order to avoid database re-querying + self._Header = 'DUMMY' + + ## Retrieve platform name + def _GetPlatformName(self): + if self._PlatformName == None: + if self._Header == None: + self._GetHeaderInfo() + if self._PlatformName == None: + EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_NAME", File=self.MetaFile) + return self._PlatformName + + ## Retrieve file guid + def _GetFileGuid(self): + if self._Guid == None: + if self._Header == None: + self._GetHeaderInfo() + if self._Guid == None: + EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No FILE_GUID", File=self.MetaFile) + return self._Guid + + ## Retrieve platform version + def _GetVersion(self): + if self._Version == None: + if self._Header == None: + self._GetHeaderInfo() + if self._Version == None: + self._Version = '' + return self._Version + + ## Retrieve platform description file version + def _GetDscSpec(self): + if self._DscSpecification == None: + if self._Header == None: + self._GetHeaderInfo() + if self._DscSpecification == None: + self._DscSpecification = '' + return self._DscSpecification + + ## Retrieve OUTPUT_DIRECTORY + def _GetOutpuDir(self): + if self._OutputDirectory == None: + if self._Header == None: + self._GetHeaderInfo() + if self._OutputDirectory == None: + self._OutputDirectory = os.path.join("Build", self._PlatformName) + return self._OutputDirectory + + ## Retrieve SUPPORTED_ARCHITECTURES + def _GetSupArch(self): + if self._SupArchList == None: + if self._Header == None: + self._GetHeaderInfo() + if self._SupArchList == None: + self._SupArchList = ARCH_LIST + return self._SupArchList + + ## Retrieve BUILD_TARGETS + def _GetBuildTarget(self): + if self._BuildTargets == None: + if self._Header == None: + self._GetHeaderInfo() + if self._BuildTargets == None: + self._BuildTargets = ['DEBUG', 'RELEASE'] + return self._BuildTargets + + ## Retrieve SKUID_IDENTIFIER + def _GetSkuName(self): + if self._SkuName == None: + if self._Header == None: + self._GetHeaderInfo() + if self._SkuName == None or self._SkuName not in self.SkuIds: + self._SkuName = 'DEFAULT' + return self._SkuName + + ## Override SKUID_IDENTIFIER + def _SetSkuName(self, Value): + if Value in self.SkuIds: + self._SkuName = Value + + def _GetFdfFile(self): + if self._FlashDefinition == None: + if self._Header == None: + self._GetHeaderInfo() + if self._FlashDefinition == None: + self._FlashDefinition = '' + return self._FlashDefinition + + ## Retrieve FLASH_DEFINITION + def _GetBuildNumber(self): + if self._BuildNumber == None: + if self._Header == None: + self._GetHeaderInfo() + if self._BuildNumber == None: + self._BuildNumber = '' + return self._BuildNumber + + ## Retrieve MAKEFILE_NAME + def _GetMakefileName(self): + if self._MakefileName == None: + if self._Header == None: + self._GetHeaderInfo() + if self._MakefileName == None: + self._MakefileName = '' + return self._MakefileName + + ## Retrieve BsBaseAddress + def _GetBsBaseAddress(self): + if self._BsBaseAddress == None: + if self._Header == None: + self._GetHeaderInfo() + if self._BsBaseAddress == None: + self._BsBaseAddress = '' + return self._BsBaseAddress + + ## Retrieve RtBaseAddress + def _GetRtBaseAddress(self): + if self._RtBaseAddress == None: + if self._Header == None: + self._GetHeaderInfo() + if self._RtBaseAddress == None: + self._RtBaseAddress = '' + return self._RtBaseAddress + + ## Retrieve [SkuIds] section information + def _GetSkuIds(self): + if self._SkuIds == None: + self._SkuIds = {} + RecordList = self._RawData[MODEL_EFI_SKU_ID] + for Record in RecordList: + if Record[0] in [None, '']: + EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID number', + File=self.MetaFile, Line=Record[-1]) + if Record[1] in [None, '']: + EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID name', + File=self.MetaFile, Line=Record[-1]) + self._SkuIds[Record[1]] = Record[0] + if 'DEFAULT' not in self._SkuIds: + self._SkuIds['DEFAULT'] = 0 + return self._SkuIds + + ## Retrieve [Components] section information + def _GetModules(self): + if self._Modules != None: + return self._Modules + + self._Modules = sdict() + RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch] + Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource} + Macros.update(self._Macros) + for Record in RecordList: + ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch) + ModuleId = Record[5] + LineNo = Record[6] + + # check the file validation + ErrorCode, ErrorInfo = ModuleFile.Validate('.inf') + if ErrorCode != 0: + EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo, + ExtraData=ErrorInfo) + # Check duplication + if ModuleFile in self._Modules: + EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo) + + Module = ModuleBuildClassObject() + Module.MetaFile = ModuleFile + + # get module override path + RecordList = self._RawData[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, self._Arch, None, ModuleId] + if RecordList != []: + Module.SourceOverridePath = os.path.join(GlobalData.gWorkspace, NormPath(RecordList[0][0], Macros)) + + # Check if the source override path exists + if not os.path.isdir(Module.SourceOverridePath): + EdkLogger.error('build', FILE_NOT_FOUND, Message = 'Source override path does not exist:', File=self.MetaFile, ExtraData=Module.SourceOverridePath, Line=LineNo) + + #Add to GlobalData Variables + GlobalData.gOverrideDir[ModuleFile.Key] = Module.SourceOverridePath + + # get module private library instance + RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, ModuleId] + for Record in RecordList: + LibraryClass = Record[0] + LibraryPath = PathClass(NormPath(Record[1], Macros), GlobalData.gWorkspace, Arch=self._Arch) + LineNo = Record[-1] + + # check the file validation + ErrorCode, ErrorInfo = LibraryPath.Validate('.inf') + if ErrorCode != 0: + EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo, + ExtraData=ErrorInfo) + + if LibraryClass == '' or LibraryClass == 'NULL': + self._NullLibraryNumber += 1 + LibraryClass = 'NULL%d' % self._NullLibraryNumber + EdkLogger.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass)) + Module.LibraryClasses[LibraryClass] = LibraryPath + if LibraryPath not in self.LibraryInstances: + self.LibraryInstances.append(LibraryPath) + + # get module private PCD setting + for Type in [MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, \ + MODEL_PCD_FEATURE_FLAG, MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]: + RecordList = self._RawData[Type, self._Arch, None, ModuleId] + for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList: + TokenList = GetSplitValueList(Setting) + DefaultValue = TokenList[0] + if len(TokenList) > 1: + MaxDatumSize = TokenList[1] + else: + MaxDatumSize = '' + TypeString = self._PCD_TYPE_STRING_[Type] + Pcd = PcdClassObject( + PcdCName, + TokenSpaceGuid, + TypeString, + '', + DefaultValue, + '', + MaxDatumSize, + {}, + None + ) + Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd + + # get module private build options + RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None, ModuleId] + for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList: + if (ToolChainFamily, ToolChain) not in Module.BuildOptions: + Module.BuildOptions[ToolChainFamily, ToolChain] = Option + else: + OptionString = Module.BuildOptions[ToolChainFamily, ToolChain] + Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option + + self._Modules[ModuleFile] = Module + return self._Modules + + ## Retrieve all possible library instances used in this platform + def _GetLibraryInstances(self): + if self._LibraryInstances == None: + self._GetLibraryClasses() + return self._LibraryInstances + + ## Retrieve [LibraryClasses] information + def _GetLibraryClasses(self): + if self._LibraryClasses == None: + self._LibraryInstances = [] + # + # tdict is a special dict kind of type, used for selecting correct + # library instance for given library class and module type + # + LibraryClassDict = tdict(True, 3) + # track all library class names + LibraryClassSet = set() + RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch] + Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource} + Macros.update(self._Macros) + for Record in RecordList: + LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy, LineNo = Record + LibraryClassSet.add(LibraryClass) + LibraryInstance = PathClass(NormPath(LibraryInstance, Macros), GlobalData.gWorkspace, Arch=self._Arch) + # check the file validation + ErrorCode, ErrorInfo = LibraryInstance.Validate('.inf') + if ErrorCode != 0: + EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo, + ExtraData=ErrorInfo) + + if ModuleType != 'COMMON' and ModuleType not in SUP_MODULE_LIST: + EdkLogger.error('build', OPTION_UNKNOWN, "Unknown module type [%s]" % ModuleType, + File=self.MetaFile, ExtraData=LibraryInstance, Line=LineNo) + LibraryClassDict[Arch, ModuleType, LibraryClass] = LibraryInstance + if LibraryInstance not in self._LibraryInstances: + self._LibraryInstances.append(LibraryInstance) + + # resolve the specific library instance for each class and each module type + self._LibraryClasses = tdict(True) + for LibraryClass in LibraryClassSet: + # try all possible module types + for ModuleType in SUP_MODULE_LIST: + LibraryInstance = LibraryClassDict[self._Arch, ModuleType, LibraryClass] + if LibraryInstance == None: + continue + self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance + + # for R8 style library instances, which are listed in different section + RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch] + for Record in RecordList: + File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch) + LineNo = Record[-1] + # check the file validation + ErrorCode, ErrorInfo = File.Validate('.inf') + if ErrorCode != 0: + EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo, + ExtraData=ErrorInfo) + if File not in self._LibraryInstances: + self._LibraryInstances.append(File) + # + # we need the module name as the library class name, so we have + # to parse it here. (self._Bdb[] will trigger a file parse if it + # hasn't been parsed) + # + Library = self._Bdb[File, self._Arch] + self._LibraryClasses[Library.BaseName, ':dummy:'] = Library + return self._LibraryClasses + + ## Retrieve all PCD settings in platform + def _GetPcds(self): + if self._Pcds == None: + self._Pcds = {} + self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD)) + self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE)) + self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG)) + self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT)) + self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII)) + self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD)) + self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT)) + self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII)) + self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD)) + return self._Pcds + + ## Retrieve [BuildOptions] + def _GetBuildOptions(self): + if self._BuildOptions == None: + self._BuildOptions = {} + RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION] + for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList: + self._BuildOptions[ToolChainFamily, ToolChain] = Option + return self._BuildOptions + + ## Retrieve non-dynamic PCD settings + # + # @param Type PCD type + # + # @retval a dict object contains settings of given PCD type + # + def _GetPcd(self, Type): + Pcds = {} + # + # tdict is a special dict kind of type, used for selecting correct + # PCD settings for certain ARCH + # + PcdDict = tdict(True, 3) + PcdSet = set() + # Find out all possible PCD candidates for self._Arch + RecordList = self._RawData[Type, self._Arch] + for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList: + PcdSet.add((PcdCName, TokenSpaceGuid)) + PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting + # Remove redundant PCD candidates + for PcdCName, TokenSpaceGuid in PcdSet: + ValueList = ['', '', ''] + Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid] + if Setting == None: + continue + TokenList = Setting.split(TAB_VALUE_SPLIT) + ValueList[0:len(TokenList)] = TokenList + PcdValue, DatumType, MaxDatumSize = ValueList + Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject( + PcdCName, + TokenSpaceGuid, + self._PCD_TYPE_STRING_[Type], + DatumType, + PcdValue, + '', + MaxDatumSize, + {}, + None + ) + return Pcds + + ## Retrieve dynamic PCD settings + # + # @param Type PCD type + # + # @retval a dict object contains settings of given PCD type + # + def _GetDynamicPcd(self, Type): + Pcds = {} + # + # tdict is a special dict kind of type, used for selecting correct + # PCD settings for certain ARCH and SKU + # + PcdDict = tdict(True, 4) + PcdSet = set() + # Find out all possible PCD candidates for self._Arch + RecordList = self._RawData[Type, self._Arch] + for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList: + PcdSet.add((PcdCName, TokenSpaceGuid)) + PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting + # Remove redundant PCD candidates, per the ARCH and SKU + for PcdCName, TokenSpaceGuid in PcdSet: + ValueList = ['', '', ''] + Setting = PcdDict[self._Arch, self.SkuName, PcdCName, TokenSpaceGuid] + if Setting == None: + continue + TokenList = Setting.split(TAB_VALUE_SPLIT) + ValueList[0:len(TokenList)] = TokenList + PcdValue, DatumType, MaxDatumSize = ValueList + + SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], '', '', '', '', '', PcdValue) + Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject( + PcdCName, + TokenSpaceGuid, + self._PCD_TYPE_STRING_[Type], + DatumType, + PcdValue, + '', + MaxDatumSize, + {self.SkuName : SkuInfo}, + None + ) + return Pcds + + ## Retrieve dynamic HII PCD settings + # + # @param Type PCD type + # + # @retval a dict object contains settings of given PCD type + # + def _GetDynamicHiiPcd(self, Type): + Pcds = {} + # + # tdict is a special dict kind of type, used for selecting correct + # PCD settings for certain ARCH and SKU + # + PcdDict = tdict(True, 4) + PcdSet = set() + RecordList = self._RawData[Type, self._Arch] + # Find out all possible PCD candidates for self._Arch + for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList: + PcdSet.add((PcdCName, TokenSpaceGuid)) + PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting + # Remove redundant PCD candidates, per the ARCH and SKU + for PcdCName, TokenSpaceGuid in PcdSet: + ValueList = ['', '', '', ''] + Setting = PcdDict[self._Arch, self.SkuName, PcdCName, TokenSpaceGuid] + if Setting == None: + continue + TokenList = Setting.split(TAB_VALUE_SPLIT) + ValueList[0:len(TokenList)] = TokenList + VariableName, VariableGuid, VariableOffset, DefaultValue = ValueList + SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue) + Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject( + PcdCName, + TokenSpaceGuid, + self._PCD_TYPE_STRING_[Type], + '', + DefaultValue, + '', + '', + {self.SkuName : SkuInfo}, + None + ) + return Pcds + + ## Retrieve dynamic VPD PCD settings + # + # @param Type PCD type + # + # @retval a dict object contains settings of given PCD type + # + def _GetDynamicVpdPcd(self, Type): + Pcds = {} + # + # tdict is a special dict kind of type, used for selecting correct + # PCD settings for certain ARCH and SKU + # + PcdDict = tdict(True, 4) + PcdSet = set() + # Find out all possible PCD candidates for self._Arch + RecordList = self._RawData[Type, self._Arch] + for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList: + PcdSet.add((PcdCName, TokenSpaceGuid)) + PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting + # Remove redundant PCD candidates, per the ARCH and SKU + for PcdCName, TokenSpaceGuid in PcdSet: + ValueList = ['', ''] + Setting = PcdDict[self._Arch, self.SkuName, PcdCName, TokenSpaceGuid] + if Setting == None: + continue + TokenList = Setting.split(TAB_VALUE_SPLIT) + ValueList[0:len(TokenList)] = TokenList + VpdOffset, MaxDatumSize = ValueList + + SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], '', '', '', '', VpdOffset) + Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject( + PcdCName, + TokenSpaceGuid, + self._PCD_TYPE_STRING_[Type], + '', + '', + '', + MaxDatumSize, + {self.SkuName : SkuInfo}, + None + ) + return Pcds + + ## Add external modules + # + # The external modules are mostly those listed in FDF file, which don't + # need "build". + # + # @param FilePath The path of module description file + # + def AddModule(self, FilePath): + FilePath = NormPath(FilePath) + if FilePath not in self.Modules: + Module = ModuleBuildClassObject() + Module.MetaFile = FilePath + self.Modules.append(Module) + + ## Add external PCDs + # + # The external PCDs are mostly those listed in FDF file to specify address + # or offset information. + # + # @param Name Name of the PCD + # @param Guid Token space guid of the PCD + # @param Value Value of the PCD + # + def AddPcd(self, Name, Guid, Value): + if (Name, Guid) not in self.Pcds: + self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, None) + self.Pcds[Name, Guid].DefaultValue = Value + + Arch = property(_GetArch, _SetArch) + Platform = property(_GetPlatformName) + PlatformName = property(_GetPlatformName) + Guid = property(_GetFileGuid) + Version = property(_GetVersion) + DscSpecification = property(_GetDscSpec) + OutputDirectory = property(_GetOutpuDir) + SupArchList = property(_GetSupArch) + BuildTargets = property(_GetBuildTarget) + SkuName = property(_GetSkuName, _SetSkuName) + FlashDefinition = property(_GetFdfFile) + BuildNumber = property(_GetBuildNumber) + MakefileName = property(_GetMakefileName) + BsBaseAddress = property(_GetBsBaseAddress) + RtBaseAddress = property(_GetRtBaseAddress) + + SkuIds = property(_GetSkuIds) + Modules = property(_GetModules) + LibraryInstances = property(_GetLibraryInstances) + LibraryClasses = property(_GetLibraryClasses) + Pcds = property(_GetPcds) + BuildOptions = property(_GetBuildOptions) + +## Platform build information from DSC file +# +# This class is used to retrieve information stored in database and convert them +# into PackageBuildClassObject form for easier use for AutoGen. +# +class DecBuildData(PackageBuildClassObject): + # dict used to convert PCD type in database to string used by build tool + _PCD_TYPE_STRING_ = { + MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild", + MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule", + MODEL_PCD_FEATURE_FLAG : "FeatureFlag", + MODEL_PCD_DYNAMIC : "Dynamic", + MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic", + MODEL_PCD_DYNAMIC_HII : "DynamicHii", + MODEL_PCD_DYNAMIC_VPD : "DynamicVpd", + MODEL_PCD_DYNAMIC_EX : "DynamicEx", + MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx", + MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii", + MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd", + } + + # dict used to convert part of [Defines] to members of DecBuildData directly + _PROPERTY_ = { + # + # Required Fields + # + TAB_DEC_DEFINES_PACKAGE_NAME : "_PackageName", + TAB_DEC_DEFINES_PACKAGE_GUID : "_Guid", + TAB_DEC_DEFINES_PACKAGE_VERSION : "_Version", + } + + + ## Constructor of DecBuildData + # + # Initialize object of DecBuildData + # + # @param FilePath The path of package description file + # @param RawData The raw data of DEC file + # @param BuildDataBase Database used to retrieve module information + # @param Arch The target architecture + # @param Platform (not used for DecBuildData) + # @param Macros Macros used for replacement in DSC file + # + def __init__(self, File, RawData, BuildDataBase, Arch='COMMON', Platform='DUMMY', Macros={}): + self.MetaFile = File + self._PackageDir = File.Dir + self._RawData = RawData + self._Bdb = BuildDataBase + self._Arch = Arch + self._Macros = Macros + self._Clear() + + ## XXX[key] = value + def __setitem__(self, key, value): + self.__dict__[self._PROPERTY_[key]] = value + + ## value = XXX[key] + def __getitem__(self, key): + return self.__dict__[self._PROPERTY_[key]] + + ## "in" test support + def __contains__(self, key): + return key in self._PROPERTY_ + + ## Set all internal used members of DecBuildData to None + def _Clear(self): + self._Header = None + self._PackageName = None + self._Guid = None + self._Version = None + self._Protocols = None + self._Ppis = None + self._Guids = None + self._Includes = None + self._LibraryClasses = None + self._Pcds = None + + ## Get architecture + def _GetArch(self): + return self._Arch + + ## Set architecture + # + # Changing the default ARCH to another may affect all other information + # because all information in a platform may be ARCH-related. That's + # why we need to clear all internal used members, in order to cause all + # information to be re-retrieved. + # + # @param Value The value of ARCH + # + def _SetArch(self, Value): + if self._Arch == Value: + return + self._Arch = Value + self._Clear() + + ## Retrieve all information in [Defines] section + # + # (Retriving all [Defines] information in one-shot is just to save time.) + # + def _GetHeaderInfo(self): + RecordList = self._RawData[MODEL_META_DATA_HEADER] + for Record in RecordList: + Name = Record[0] + if Name in self: + self[Name] = Record[1] + self._Header = 'DUMMY' + + ## Retrieve package name + def _GetPackageName(self): + if self._PackageName == None: + if self._Header == None: + self._GetHeaderInfo() + if self._PackageName == None: + EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_NAME", File=self.MetaFile) + return self._PackageName + + ## Retrieve file guid + def _GetFileGuid(self): + if self._Guid == None: + if self._Header == None: + self._GetHeaderInfo() + if self._Guid == None: + EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_GUID", File=self.MetaFile) + return self._Guid + + ## Retrieve package version + def _GetVersion(self): + if self._Version == None: + if self._Header == None: + self._GetHeaderInfo() + if self._Version == None: + self._Version = '' + return self._Version + + ## Retrieve protocol definitions (name/value pairs) + def _GetProtocol(self): + if self._Protocols == None: + # + # tdict is a special kind of dict, used for selecting correct + # protocol defition for given ARCH + # + ProtocolDict = tdict(True) + NameList = [] + # find out all protocol definitions for specific and 'common' arch + RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch] + for Name, Guid, Dummy, Arch, ID, LineNo in RecordList: + if Name not in NameList: + NameList.append(Name) + ProtocolDict[Arch, Name] = Guid + # use sdict to keep the order + self._Protocols = sdict() + for Name in NameList: + # + # limit the ARCH to self._Arch, if no self._Arch found, tdict + # will automatically turn to 'common' ARCH for trying + # + self._Protocols[Name] = ProtocolDict[self._Arch, Name] + return self._Protocols + + ## Retrieve PPI definitions (name/value pairs) + def _GetPpi(self): + if self._Ppis == None: + # + # tdict is a special kind of dict, used for selecting correct + # PPI defition for given ARCH + # + PpiDict = tdict(True) + NameList = [] + # find out all PPI definitions for specific arch and 'common' arch + RecordList = self._RawData[MODEL_EFI_PPI, self._Arch] + for Name, Guid, Dummy, Arch, ID, LineNo in RecordList: + if Name not in NameList: + NameList.append(Name) + PpiDict[Arch, Name] = Guid + # use sdict to keep the order + self._Ppis = sdict() + for Name in NameList: + # + # limit the ARCH to self._Arch, if no self._Arch found, tdict + # will automatically turn to 'common' ARCH for trying + # + self._Ppis[Name] = PpiDict[self._Arch, Name] + return self._Ppis + + ## Retrieve GUID definitions (name/value pairs) + def _GetGuid(self): + if self._Guids == None: + # + # tdict is a special kind of dict, used for selecting correct + # GUID defition for given ARCH + # + GuidDict = tdict(True) + NameList = [] + # find out all protocol definitions for specific and 'common' arch + RecordList = self._RawData[MODEL_EFI_GUID, self._Arch] + for Name, Guid, Dummy, Arch, ID, LineNo in RecordList: + if Name not in NameList: + NameList.append(Name) + GuidDict[Arch, Name] = Guid + # use sdict to keep the order + self._Guids = sdict() + for Name in NameList: + # + # limit the ARCH to self._Arch, if no self._Arch found, tdict + # will automatically turn to 'common' ARCH for trying + # + self._Guids[Name] = GuidDict[self._Arch, Name] + return self._Guids + + ## Retrieve public include paths declared in this package + def _GetInclude(self): + if self._Includes == None: + self._Includes = [] + RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch] + Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource} + Macros.update(self._Macros) + for Record in RecordList: + File = PathClass(NormPath(Record[0], Macros), self._PackageDir, Arch=self._Arch) + LineNo = Record[-1] + # validate the path + ErrorCode, ErrorInfo = File.Validate() + if ErrorCode != 0: + EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo) + + # avoid duplicate include path + if File not in self._Includes: + self._Includes.append(File) + return self._Includes + + ## Retrieve library class declarations (not used in build at present) + def _GetLibraryClass(self): + if self._LibraryClasses == None: + # + # tdict is a special kind of dict, used for selecting correct + # library class declaration for given ARCH + # + LibraryClassDict = tdict(True) + LibraryClassSet = set() + RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch] + Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource} + Macros.update(self._Macros) + for LibraryClass, File, Dummy, Arch, ID, LineNo in RecordList: + File = PathClass(NormPath(File, Macros), self._PackageDir, Arch=self._Arch) + # check the file validation + ErrorCode, ErrorInfo = File.Validate() + if ErrorCode != 0: + EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo) + LibraryClassSet.add(LibraryClass) + LibraryClassDict[Arch, LibraryClass] = File + self._LibraryClasses = sdict() + for LibraryClass in LibraryClassSet: + self._LibraryClasses[LibraryClass] = LibraryClassDict[self._Arch, LibraryClass] + return self._LibraryClasses + + ## Retrieve PCD declarations + def _GetPcds(self): + if self._Pcds == None: + self._Pcds = {} + self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD)) + self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE)) + self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG)) + self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC)) + self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX)) + return self._Pcds + + ## Retrieve PCD declarations for given type + def _GetPcd(self, Type): + Pcds = {} + # + # tdict is a special kind of dict, used for selecting correct + # PCD declaration for given ARCH + # + PcdDict = tdict(True, 3) + # for summarizing PCD + PcdSet = set() + # find out all PCDs of the 'type' + RecordList = self._RawData[Type, self._Arch] + for TokenSpaceGuid, PcdCName, Setting, Arch, Dummy1, Dummy2 in RecordList: + PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting + PcdSet.add((PcdCName, TokenSpaceGuid)) + + for PcdCName, TokenSpaceGuid in PcdSet: + ValueList = ['', '', ''] + # + # limit the ARCH to self._Arch, if no self._Arch found, tdict + # will automatically turn to 'common' ARCH and try again + # + Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid] + if Setting == None: + continue + TokenList = Setting.split(TAB_VALUE_SPLIT) + ValueList[0:len(TokenList)] = TokenList + DefaultValue, DatumType, TokenNumber = ValueList + Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdClassObject( + PcdCName, + TokenSpaceGuid, + self._PCD_TYPE_STRING_[Type], + DatumType, + DefaultValue, + TokenNumber, + '', + {}, + None + ) + return Pcds + + + Arch = property(_GetArch, _SetArch) + PackageName = property(_GetPackageName) + Guid = property(_GetFileGuid) + Version = property(_GetVersion) + + Protocols = property(_GetProtocol) + Ppis = property(_GetPpi) + Guids = property(_GetGuid) + Includes = property(_GetInclude) + LibraryClasses = property(_GetLibraryClass) + Pcds = property(_GetPcds) + +## Module build information from INF file +# +# This class is used to retrieve information stored in database and convert them +# into ModuleBuildClassObject form for easier use for AutoGen. +# +class InfBuildData(ModuleBuildClassObject): + # dict used to convert PCD type in database to string used by build tool + _PCD_TYPE_STRING_ = { + MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild", + MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule", + MODEL_PCD_FEATURE_FLAG : "FeatureFlag", + MODEL_PCD_DYNAMIC : "Dynamic", + MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic", + MODEL_PCD_DYNAMIC_HII : "DynamicHii", + MODEL_PCD_DYNAMIC_VPD : "DynamicVpd", + MODEL_PCD_DYNAMIC_EX : "DynamicEx", + MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx", + MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii", + MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd", + } + + # dict used to convert part of [Defines] to members of InfBuildData directly + _PROPERTY_ = { + # + # Required Fields + # + TAB_INF_DEFINES_BASE_NAME : "_BaseName", + TAB_INF_DEFINES_FILE_GUID : "_Guid", + TAB_INF_DEFINES_MODULE_TYPE : "_ModuleType", + # + # Optional Fields + # + TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion", + TAB_INF_DEFINES_COMPONENT_TYPE : "_ComponentType", + TAB_INF_DEFINES_MAKEFILE_NAME : "_MakefileName", + #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile", + TAB_INF_DEFINES_VERSION_NUMBER : "_Version", + TAB_INF_DEFINES_VERSION_STRING : "_Version", + TAB_INF_DEFINES_VERSION : "_Version", + TAB_INF_DEFINES_PCD_IS_DRIVER : "_PcdIsDriver", + TAB_INF_DEFINES_SHADOW : "_Shadow", + + TAB_COMPONENTS_SOURCE_OVERRIDE_PATH : "_SourceOverridePath", + } + + # dict used to convert Component type to Module type + _MODULE_TYPE_ = { + "LIBRARY" : "BASE", + "SECURITY_CORE" : "SEC", + "PEI_CORE" : "PEI_CORE", + "COMBINED_PEIM_DRIVER" : "PEIM", + "PIC_PEIM" : "PEIM", + "RELOCATABLE_PEIM" : "PEIM", + "PE32_PEIM" : "PEIM", + "BS_DRIVER" : "DXE_DRIVER", + "RT_DRIVER" : "DXE_RUNTIME_DRIVER", + "SAL_RT_DRIVER" : "DXE_SAL_DRIVER", + # "BS_DRIVER" : "DXE_SMM_DRIVER", + # "BS_DRIVER" : "UEFI_DRIVER", + "APPLICATION" : "UEFI_APPLICATION", + "LOGO" : "BASE", + } + + # regular expression for converting XXX_FLAGS in [nmake] section to new type + _NMAKE_FLAG_PATTERN_ = re.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re.UNICODE) + # dict used to convert old tool name used in [nmake] section to new ones + _TOOL_CODE_ = { + "C" : "CC", + "LIB" : "SLINK", + "LINK" : "DLINK", + } + + + ## Constructor of DscBuildData + # + # Initialize object of DscBuildData + # + # @param FilePath The path of platform description file + # @param RawData The raw data of DSC file + # @param BuildDataBase Database used to retrieve module/package information + # @param Arch The target architecture + # @param Platform The name of platform employing this module + # @param Macros Macros used for replacement in DSC file + # + def __init__(self, FilePath, RawData, BuildDatabase, Arch='COMMON', Platform='COMMON', Macros={}): + self.MetaFile = FilePath + self._ModuleDir = FilePath.Dir + self._RawData = RawData + self._Bdb = BuildDatabase + self._Arch = Arch + self._Platform = 'COMMON' + self._Macros = Macros + self._SourceOverridePath = None + if FilePath.Key in GlobalData.gOverrideDir: + self._SourceOverridePath = GlobalData.gOverrideDir[FilePath.Key] + self._Clear() + + ## XXX[key] = value + def __setitem__(self, key, value): + self.__dict__[self._PROPERTY_[key]] = value + + ## value = XXX[key] + def __getitem__(self, key): + return self.__dict__[self._PROPERTY_[key]] + + ## "in" test support + def __contains__(self, key): + return key in self._PROPERTY_ + + ## Set all internal used members of InfBuildData to None + def _Clear(self): + self._Header_ = None + self._AutoGenVersion = None + self._BaseName = None + self._ModuleType = None + self._ComponentType = None + self._BuildType = None + self._Guid = None + self._Version = None + self._PcdIsDriver = None + self._BinaryModule = None + self._Shadow = None + self._MakefileName = None + self._CustomMakefile = None + self._Specification = None + self._LibraryClass = None + self._ModuleEntryPointList = None + self._ModuleUnloadImageList = None + self._ConstructorList = None + self._DestructorList = None + self._Defs = None + self._Binaries = None + self._Sources = None + self._LibraryClasses = None + self._Libraries = None + self._Protocols = None + self._Ppis = None + self._Guids = None + self._Includes = None + self._Packages = None + self._Pcds = None + self._BuildOptions = None + self._Depex = None + #self._SourceOverridePath = None + + ## Get architecture + def _GetArch(self): + return self._Arch + + ## Set architecture + # + # Changing the default ARCH to another may affect all other information + # because all information in a platform may be ARCH-related. That's + # why we need to clear all internal used members, in order to cause all + # information to be re-retrieved. + # + # @param Value The value of ARCH + # + def _SetArch(self, Value): + if self._Arch == Value: + return + self._Arch = Value + self._Clear() + + ## Return the name of platform employing this module + def _GetPlatform(self): + return self._Platform + + ## Change the name of platform employing this module + # + # Changing the default name of platform to another may affect some information + # because they may be PLATFORM-related. That's why we need to clear all internal + # used members, in order to cause all information to be re-retrieved. + # + def _SetPlatform(self, Value): + if self._Platform == Value: + return + self._Platform = Value + self._Clear() + + ## Retrieve all information in [Defines] section + # + # (Retriving all [Defines] information in one-shot is just to save time.) + # + def _GetHeaderInfo(self): + RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform] + for Record in RecordList: + Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False) + Name = Record[0] + # items defined _PROPERTY_ don't need additional processing + if Name in self: + self[Name] = Record[1] + # some special items in [Defines] section need special treatment + elif Name == 'EFI_SPECIFICATION_VERSION': + if self._Specification == None: + self._Specification = sdict() + self._Specification[Name] = Record[1] + elif Name == 'EDK_RELEASE_VERSION': + if self._Specification == None: + self._Specification = sdict() + self._Specification[Name] = Record[1] + elif Name == 'PI_SPECIFICATION_VERSION': + if self._Specification == None: + self._Specification = sdict() + self._Specification[Name] = Record[1] + elif Name == 'LIBRARY_CLASS': + if self._LibraryClass == None: + self._LibraryClass = [] + ValueList = GetSplitValueList(Record[1]) + LibraryClass = ValueList[0] + if len(ValueList) > 1: + SupModuleList = GetSplitValueList(ValueList[1], ' ') + else: + SupModuleList = SUP_MODULE_LIST + self._LibraryClass.append(LibraryClassObject(LibraryClass, SupModuleList)) + elif Name == 'ENTRY_POINT': + if self._ModuleEntryPointList == None: + self._ModuleEntryPointList = [] + self._ModuleEntryPointList.append(Record[1]) + elif Name == 'UNLOAD_IMAGE': + if self._ModuleUnloadImageList == None: + self._ModuleUnloadImageList = [] + if Record[1] == '': + continue + self._ModuleUnloadImageList.append(Record[1]) + elif Name == 'CONSTRUCTOR': + if self._ConstructorList == None: + self._ConstructorList = [] + if Record[1] == '': + continue + self._ConstructorList.append(Record[1]) + elif Name == 'DESTRUCTOR': + if self._DestructorList == None: + self._DestructorList = [] + if Record[1] == '': + continue + self._DestructorList.append(Record[1]) + elif Name == TAB_INF_DEFINES_CUSTOM_MAKEFILE: + TokenList = GetSplitValueList(Record[1]) + if self._CustomMakefile == None: + self._CustomMakefile = {} + if len(TokenList) < 2: + self._CustomMakefile['MSFT'] = TokenList[0] + self._CustomMakefile['GCC'] = TokenList[0] + else: + if TokenList[0] not in ['MSFT', 'GCC']: + EdkLogger.error("build", FORMAT_NOT_SUPPORTED, + "No supported family [%s]" % TokenList[0], + File=self.MetaFile, Line=Record[-1]) + self._CustomMakefile[TokenList[0]] = TokenList[1] + else: + if self._Defs == None: + self._Defs = sdict() + self._Defs[Name] = Record[1] + + # + # Retrieve information in sections specific to R8.x modules + # + if self._AutoGenVersion >= 0x00010005: # _AutoGenVersion may be None, which is less than anything + if not self._ModuleType: + EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, + "MODULE_TYPE is not given", File=self.MetaFile) + if self._Defs and 'PCI_DEVICE_ID' in self._Defs and 'PCI_VENDOR_ID' in self._Defs \ + and 'PCI_CLASS_CODE' in self._Defs: + self._BuildType = 'UEFI_OPTIONROM' + else: + self._BuildType = self._ModuleType.upper() + else: + self._BuildType = self._ComponentType.upper() + if not self._ComponentType: + EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, + "COMPONENT_TYPE is not given", File=self.MetaFile) + if self._ComponentType in self._MODULE_TYPE_: + self._ModuleType = self._MODULE_TYPE_[self._ComponentType] + if self._ComponentType == 'LIBRARY': + self._LibraryClass = [LibraryClassObject(self._BaseName, SUP_MODULE_LIST)] + # make use some [nmake] section macros + RecordList = self._RawData[MODEL_META_DATA_NMAKE, self._Arch, self._Platform] + for Name,Value,Dummy,Arch,Platform,ID,LineNo in RecordList: + Value = Value.replace('$(PROCESSOR)', self._Arch) + Name = Name.replace('$(PROCESSOR)', self._Arch) + Name, Value = ReplaceMacros((Name, Value), GlobalData.gEdkGlobal, True) + if Name == "IMAGE_ENTRY_POINT": + if self._ModuleEntryPointList == None: + self._ModuleEntryPointList = [] + self._ModuleEntryPointList.append(Value) + elif Name == "DPX_SOURCE": + Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource} + Macros.update(self._Macros) + File = PathClass(NormPath(Value, Macros), self._ModuleDir, Arch=self._Arch) + # check the file validation + ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False) + if ErrorCode != 0: + EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, + File=self.MetaFile, Line=LineNo) + if self.Sources == None: + self._Sources = [] + self._Sources.append(File) + else: + ToolList = self._NMAKE_FLAG_PATTERN_.findall(Name) + if len(ToolList) == 0 or len(ToolList) != 1: + pass +# EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name, +# File=self.MetaFile, Line=LineNo) + else: + if self._BuildOptions == None: + self._BuildOptions = sdict() + + if ToolList[0] in self._TOOL_CODE_: + Tool = self._TOOL_CODE_[ToolList[0]] + else: + Tool = ToolList[0] + ToolChain = "*_*_*_%s_FLAGS" % Tool + ToolChainFamily = 'MSFT' # R8.x only support MSFT tool chain + #ignore not replaced macros in value + ValueList = GetSplitValueList(' ' + Value, '/D') + Dummy = ValueList[0] + for Index in range(1, len(ValueList)): + if ValueList[Index][-1] == '=' or ValueList[Index] == '': + continue + Dummy = Dummy + ' /D ' + ValueList[Index] + Value = Dummy.strip() + if (ToolChainFamily, ToolChain) not in self._BuildOptions: + self._BuildOptions[ToolChainFamily, ToolChain] = Value + else: + OptionString = self._BuildOptions[ToolChainFamily, ToolChain] + self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Value + # set _Header to non-None in order to avoid database re-querying + self._Header_ = 'DUMMY' + + ## Retrieve file version + def _GetInfVersion(self): + if self._AutoGenVersion == None: + if self._Header_ == None: + self._GetHeaderInfo() + if self._AutoGenVersion == None: + self._AutoGenVersion = 0x00010000 + return self._AutoGenVersion + + ## Retrieve BASE_NAME + def _GetBaseName(self): + if self._BaseName == None: + if self._Header_ == None: + self._GetHeaderInfo() + if self._BaseName == None: + EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BASE_NAME name", File=self.MetaFile) + return self._BaseName + + ## Retrieve MODULE_TYPE + def _GetModuleType(self): + if self._ModuleType == None: + if self._Header_ == None: + self._GetHeaderInfo() + if self._ModuleType == None: + self._ModuleType = 'BASE' + if self._ModuleType not in SUP_MODULE_LIST: + self._ModuleType = "USER_DEFINED" + return self._ModuleType + + ## Retrieve COMPONENT_TYPE + def _GetComponentType(self): + if self._ComponentType == None: + if self._Header_ == None: + self._GetHeaderInfo() + if self._ComponentType == None: + self._ComponentType = 'USER_DEFINED' + return self._ComponentType + + ## Retrieve "BUILD_TYPE" + def _GetBuildType(self): + if self._BuildType == None: + if self._Header_ == None: + self._GetHeaderInfo() + if not self._BuildType: + self._BuildType = "BASE" + return self._BuildType + + ## Retrieve file guid + def _GetFileGuid(self): + if self._Guid == None: + if self._Header_ == None: + self._GetHeaderInfo() + if self._Guid == None: + self._Guid = '00000000-0000-0000-000000000000' + return self._Guid + + ## Retrieve module version + def _GetVersion(self): + if self._Version == None: + if self._Header_ == None: + self._GetHeaderInfo() + if self._Version == None: + self._Version = '0.0' + return self._Version + + ## Retrieve PCD_IS_DRIVER + def _GetPcdIsDriver(self): + if self._PcdIsDriver == None: + if self._Header_ == None: + self._GetHeaderInfo() + if self._PcdIsDriver == None: + self._PcdIsDriver = '' + return self._PcdIsDriver + + ## Retrieve SHADOW + def _GetShadow(self): + if self._Shadow == None: + if self._Header_ == None: + self._GetHeaderInfo() + if self._Shadow != None and self._Shadow.upper() == 'TRUE': + self._Shadow = True + else: + self._Shadow = False + return self._Shadow + + ## Retrieve CUSTOM_MAKEFILE + def _GetMakefile(self): + if self._CustomMakefile == None: + if self._Header_ == None: + self._GetHeaderInfo() + if self._CustomMakefile == None: + self._CustomMakefile = {} + return self._CustomMakefile + + ## Retrieve EFI_SPECIFICATION_VERSION + def _GetSpec(self): + if self._Specification == None: + if self._Header_ == None: + self._GetHeaderInfo() + if self._Specification == None: + self._Specification = {} + return self._Specification + + ## Retrieve LIBRARY_CLASS + def _GetLibraryClass(self): + if self._LibraryClass == None: + if self._Header_ == None: + self._GetHeaderInfo() + if self._LibraryClass == None: + self._LibraryClass = [] + return self._LibraryClass + + ## Retrieve ENTRY_POINT + def _GetEntryPoint(self): + if self._ModuleEntryPointList == None: + if self._Header_ == None: + self._GetHeaderInfo() + if self._ModuleEntryPointList == None: + self._ModuleEntryPointList = [] + return self._ModuleEntryPointList + + ## Retrieve UNLOAD_IMAGE + def _GetUnloadImage(self): + if self._ModuleUnloadImageList == None: + if self._Header_ == None: + self._GetHeaderInfo() + if self._ModuleUnloadImageList == None: + self._ModuleUnloadImageList = [] + return self._ModuleUnloadImageList + + ## Retrieve CONSTRUCTOR + def _GetConstructor(self): + if self._ConstructorList == None: + if self._Header_ == None: + self._GetHeaderInfo() + if self._ConstructorList == None: + self._ConstructorList = [] + return self._ConstructorList + + ## Retrieve DESTRUCTOR + def _GetDestructor(self): + if self._DestructorList == None: + if self._Header_ == None: + self._GetHeaderInfo() + if self._DestructorList == None: + self._DestructorList = [] + return self._DestructorList + + ## Retrieve definies other than above ones + def _GetDefines(self): + if self._Defs == None: + if self._Header_ == None: + self._GetHeaderInfo() + if self._Defs == None: + self._Defs = sdict() + return self._Defs + + ## Retrieve binary files + def _GetBinaryFiles(self): + if self._Binaries == None: + self._Binaries = [] + RecordList = self._RawData[MODEL_EFI_BINARY_FILE, self._Arch, self._Platform] + Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource, 'PROCESSOR':self._Arch} + Macros.update(self._Macros) + for Record in RecordList: + Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False) + FileType = Record[0] + LineNo = Record[-1] + Target = 'COMMON' + FeatureFlag = [] + if Record[2]: + TokenList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT) + if TokenList: + Target = TokenList[0] + if len(TokenList) > 1: + FeatureFlag = Record[1:] + + File = PathClass(NormPath(Record[1], Macros), self._ModuleDir, '', FileType, True, self._Arch, '', Target) + # check the file validation + ErrorCode, ErrorInfo = File.Validate() + if ErrorCode != 0: + EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo) + self._Binaries.append(File) + return self._Binaries + + ## Retrieve source files + def _GetSourceFiles(self): + if self._Sources == None: + self._Sources = [] + RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform] + Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource, 'PROCESSOR':self._Arch} + Macros.update(self._Macros) + for Record in RecordList: + Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False) + LineNo = Record[-1] + ToolChainFamily = Record[1] + TagName = Record[2] + ToolCode = Record[3] + FeatureFlag = Record[4] + if self._AutoGenVersion < 0x00010005: + # old module source files (R8) + File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, self._SourceOverridePath, + '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode) + # check the file validation + ErrorCode, ErrorInfo = File.Validate(CaseSensitive=False) + if ErrorCode != 0: + if File.Ext.lower() == '.h': + EdkLogger.warn('build', 'Include file not found', ExtraData=ErrorInfo, + File=self.MetaFile, Line=LineNo) + continue + else: + EdkLogger.error('build', ErrorCode, ExtraData=File, File=self.MetaFile, Line=LineNo) + else: + File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, '', + '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode) + # check the file validation + ErrorCode, ErrorInfo = File.Validate() + if ErrorCode != 0: + EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo) + + self._Sources.append(File) + return self._Sources + + ## Retrieve library classes employed by this module + def _GetLibraryClassUses(self): + if self._LibraryClasses == None: + self._LibraryClasses = sdict() + RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, self._Platform] + for Record in RecordList: + Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False) + Lib = Record[0] + Instance = Record[1] + if Instance != None and Instance != '': + Instance = NormPath(Instance, self._Macros) + self._LibraryClasses[Lib] = Instance + return self._LibraryClasses + + ## Retrieve library names (for R8.x style of modules) + def _GetLibraryNames(self): + if self._Libraries == None: + self._Libraries = [] + RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch, self._Platform] + for Record in RecordList: + # in case of name with '.lib' extension, which is unusual in R8.x inf + Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False) + LibraryName = os.path.splitext(Record[0])[0] + if LibraryName not in self._Libraries: + self._Libraries.append(LibraryName) + return self._Libraries + + ## Retrieve protocols consumed/produced by this module + def _GetProtocols(self): + if self._Protocols == None: + self._Protocols = sdict() + RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform] + for Record in RecordList: + CName = Record[0] + Value = ProtocolValue(CName, self.Packages) + if Value == None: + PackageList = "\n\t".join([str(P) for P in self.Packages]) + EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, + "Value of Protocol [%s] is not found under [Protocols] section in" % CName, + ExtraData=PackageList, File=self.MetaFile, Line=Record[-1]) + self._Protocols[CName] = Value + return self._Protocols + + ## Retrieve PPIs consumed/produced by this module + def _GetPpis(self): + if self._Ppis == None: + self._Ppis = sdict() + RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform] + for Record in RecordList: + CName = Record[0] + Value = PpiValue(CName, self.Packages) + if Value == None: + PackageList = "\n\t".join([str(P) for P in self.Packages]) + EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, + "Value of PPI [%s] is not found under [Ppis] section in " % CName, + ExtraData=PackageList, File=self.MetaFile, Line=Record[-1]) + self._Ppis[CName] = Value + return self._Ppis + + ## Retrieve GUIDs consumed/produced by this module + def _GetGuids(self): + if self._Guids == None: + self._Guids = sdict() + RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform] + for Record in RecordList: + CName = Record[0] + Value = GuidValue(CName, self.Packages) + if Value == None: + PackageList = "\n\t".join([str(P) for P in self.Packages]) + EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, + "Value of Guid [%s] is not found under [Guids] section in" % CName, + ExtraData=PackageList, File=self.MetaFile, Line=Record[-1]) + self._Guids[CName] = Value + return self._Guids + + ## Retrieve include paths necessary for this module (for R8.x style of modules) + def _GetIncludes(self): + if self._Includes == None: + self._Includes = [] + if self._SourceOverridePath: + self._Includes.append(self._SourceOverridePath) + RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch, self._Platform] + # [includes] section must be used only in old (R8.x) inf file + if self.AutoGenVersion >= 0x00010005 and len(RecordList) > 0: + EdkLogger.error('build', FORMAT_NOT_SUPPORTED, "No [include] section allowed", + File=self.MetaFile, Line=RecordList[0][-1]-1) + for Record in RecordList: + Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False) + Record[0] = Record[0].replace('$(PROCESSOR)', self._Arch) + Record[0] = ReplaceMacro(Record[0], {'EFI_SOURCE' : GlobalData.gEfiSource}, False) + if Record[0].find('EDK_SOURCE') > -1: + File = NormPath(ReplaceMacro(Record[0], {'EDK_SOURCE' : GlobalData.gEcpSource}, False), self._Macros) + if File[0] == '.': + File = os.path.join(self._ModuleDir, File) + else: + File = os.path.join(GlobalData.gWorkspace, File) + File = RealPath(os.path.normpath(File)) + if File: + self._Includes.append(File) + + #TRICK: let compiler to choose correct header file + File = NormPath(ReplaceMacro(Record[0], {'EDK_SOURCE' : GlobalData.gEdkSource}, False), self._Macros) + if File[0] == '.': + File = os.path.join(self._ModuleDir, File) + else: + File = os.path.join(GlobalData.gWorkspace, File) + File = RealPath(os.path.normpath(File)) + if File: + self._Includes.append(File) + else: + File = NormPath(Record[0], self._Macros) + if File[0] == '.': + File = os.path.join(self._ModuleDir, File) + else: + File = os.path.join(GlobalData.gWorkspace, File) + File = RealPath(os.path.normpath(File)) + if File: + self._Includes.append(File) + return self._Includes + + ## Retrieve packages this module depends on + def _GetPackages(self): + if self._Packages == None: + self._Packages = [] + RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch, self._Platform] + Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource} + Macros.update(self._Macros) + for Record in RecordList: + File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch) + LineNo = Record[-1] + # check the file validation + ErrorCode, ErrorInfo = File.Validate('.dec') + if ErrorCode != 0: + EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo) + # parse this package now. we need it to get protocol/ppi/guid value + Package = self._Bdb[File, self._Arch] + self._Packages.append(Package) + return self._Packages + + ## Retrieve PCDs used in this module + def _GetPcds(self): + if self._Pcds == None: + self._Pcds = {} + self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD)) + self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE)) + self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG)) + self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC)) + self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX)) + return self._Pcds + + ## Retrieve build options specific to this module + def _GetBuildOptions(self): + if self._BuildOptions == None: + self._BuildOptions = sdict() + RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, self._Platform] + for Record in RecordList: + ToolChainFamily = Record[0] + ToolChain = Record[1] + Option = Record[2] + if (ToolChainFamily, ToolChain) not in self._BuildOptions: + self._BuildOptions[ToolChainFamily, ToolChain] = Option + else: + # concatenate the option string if they're for the same tool + OptionString = self._BuildOptions[ToolChainFamily, ToolChain] + self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option + return self._BuildOptions + + ## Retrieve depedency expression + def _GetDepex(self): + if self._Depex == None: + self._Depex = tdict(False, 2) + RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch] + Depex = {} + for Record in RecordList: + Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False) + Arch = Record[3] + ModuleType = Record[4] + TokenList = Record[0].split() + if (Arch, ModuleType) not in Depex: + Depex[Arch, ModuleType] = [] + DepexList = Depex[Arch, ModuleType] + for Token in TokenList: + if Token in DEPEX_SUPPORTED_OPCODE: + DepexList.append(Token) + elif Token.endswith(".inf"): # module file name + ModuleFile = os.path.normpath(Token) + Module = self.BuildDatabase[ModuleFile] + if Module == None: + EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "Module is not found in active platform", + ExtraData=Token, File=self.MetaFile, Line=Record[-1]) + DepexList.append(Module.Guid) + else: + # get the GUID value now + Value = ProtocolValue(Token, self.Packages) + if Value == None: + Value = PpiValue(Token, self.Packages) + if Value == None: + Value = GuidValue(Token, self.Packages) + if Value == None: + PackageList = "\n\t".join([str(P) for P in self.Packages]) + EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, + "Value of [%s] is not found in" % Token, + ExtraData=PackageList, File=self.MetaFile, Line=Record[-1]) + DepexList.append(Value) + for Arch, ModuleType in Depex: + self._Depex[Arch, ModuleType] = Depex[Arch, ModuleType] + return self._Depex + + ## Retrieve PCD for given type + def _GetPcd(self, Type): + Pcds = {} + PcdDict = tdict(True, 4) + PcdSet = set() + RecordList = self._RawData[Type, self._Arch, self._Platform] + for TokenSpaceGuid, PcdCName, Setting, Arch, Platform, Dummy1, LineNo in RecordList: + PcdDict[Arch, Platform, PcdCName, TokenSpaceGuid] = (Setting, LineNo) + PcdSet.add((PcdCName, TokenSpaceGuid)) + # get the guid value + if TokenSpaceGuid not in self.Guids: + Value = GuidValue(TokenSpaceGuid, self.Packages) + if Value == None: + PackageList = "\n\t".join([str(P) for P in self.Packages]) + EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, + "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid, + ExtraData=PackageList, File=self.MetaFile, Line=LineNo) + self.Guids[TokenSpaceGuid] = Value + + # resolve PCD type, value, datum info, etc. by getting its definition from package + for PcdCName, TokenSpaceGuid in PcdSet: + ValueList = ['', ''] + Setting, LineNo = PcdDict[self._Arch, self.Platform, PcdCName, TokenSpaceGuid] + if Setting == None: + continue + TokenList = Setting.split(TAB_VALUE_SPLIT) + ValueList[0:len(TokenList)] = TokenList + DefaultValue = ValueList[0] + Pcd = PcdClassObject( + PcdCName, + TokenSpaceGuid, + '', + '', + DefaultValue, + '', + '', + {}, + self.Guids[TokenSpaceGuid] + ) + + # get necessary info from package declaring this PCD + for Package in self.Packages: + # + # 'dynamic' in INF means its type is determined by platform; + # if platform doesn't give its type, use 'lowest' one in the + # following order, if any + # + # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx" + # + PcdType = self._PCD_TYPE_STRING_[Type] + if Type in [MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]: + Pcd.Pending = True + for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]: + if (PcdCName, TokenSpaceGuid, T) in Package.Pcds: + PcdType = T + break + else: + Pcd.Pending = False + + if (PcdCName, TokenSpaceGuid, PcdType) in Package.Pcds: + PcdInPackage = Package.Pcds[PcdCName, TokenSpaceGuid, PcdType] + Pcd.Type = PcdType + Pcd.TokenValue = PcdInPackage.TokenValue + Pcd.DatumType = PcdInPackage.DatumType + Pcd.MaxDatumSize = PcdInPackage.MaxDatumSize + if Pcd.DefaultValue in [None, '']: + Pcd.DefaultValue = PcdInPackage.DefaultValue + break + else: + EdkLogger.error( + 'build', + PARSER_ERROR, + "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdCName, self.MetaFile), + File =self.MetaFile, Line=LineNo, + ExtraData="\t%s" % '\n\t'.join([str(P) for P in self.Packages]) + ) + Pcds[PcdCName, TokenSpaceGuid] = Pcd + return Pcds + + Arch = property(_GetArch, _SetArch) + Platform = property(_GetPlatform, _SetPlatform) + + AutoGenVersion = property(_GetInfVersion) + BaseName = property(_GetBaseName) + ModuleType = property(_GetModuleType) + ComponentType = property(_GetComponentType) + BuildType = property(_GetBuildType) + Guid = property(_GetFileGuid) + Version = property(_GetVersion) + PcdIsDriver = property(_GetPcdIsDriver) + Shadow = property(_GetShadow) + CustomMakefile = property(_GetMakefile) + Specification = property(_GetSpec) + LibraryClass = property(_GetLibraryClass) + ModuleEntryPointList = property(_GetEntryPoint) + ModuleUnloadImageList = property(_GetUnloadImage) + ConstructorList = property(_GetConstructor) + DestructorList = property(_GetDestructor) + Defines = property(_GetDefines) + + Binaries = property(_GetBinaryFiles) + Sources = property(_GetSourceFiles) + LibraryClasses = property(_GetLibraryClassUses) + Libraries = property(_GetLibraryNames) + Protocols = property(_GetProtocols) + Ppis = property(_GetPpis) + Guids = property(_GetGuids) + Includes = property(_GetIncludes) + Packages = property(_GetPackages) + Pcds = property(_GetPcds) + BuildOptions = property(_GetBuildOptions) + Depex = property(_GetDepex) + +## Database +# +# This class defined the build databse for all modules, packages and platform. +# It will call corresponding parser for the given file if it cannot find it in +# the database. +# +# @param DbPath Path of database file +# @param GlobalMacros Global macros used for replacement during file parsing +# @prarm RenewDb=False Create new database file if it's already there +# +class WorkspaceDatabase(object): + # file parser + _FILE_PARSER_ = { + MODEL_FILE_INF : InfParser, + MODEL_FILE_DEC : DecParser, + MODEL_FILE_DSC : DscParser, + MODEL_FILE_FDF : None, #FdfParser, + MODEL_FILE_CIF : None + } + + # file table + _FILE_TABLE_ = { + MODEL_FILE_INF : ModuleTable, + MODEL_FILE_DEC : PackageTable, + MODEL_FILE_DSC : PlatformTable, + } + + # default database file path + _DB_PATH_ = "Conf/.cache/build.db" + + # + # internal class used for call corresponding file parser and caching the result + # to avoid unnecessary re-parsing + # + class BuildObjectFactory(object): + _FILE_TYPE_ = { + ".inf" : MODEL_FILE_INF, + ".dec" : MODEL_FILE_DEC, + ".dsc" : MODEL_FILE_DSC, + ".fdf" : MODEL_FILE_FDF, + } + + # convert to xxxBuildData object + _GENERATOR_ = { + MODEL_FILE_INF : InfBuildData, + MODEL_FILE_DEC : DecBuildData, + MODEL_FILE_DSC : DscBuildData, + MODEL_FILE_FDF : None #FlashDefTable, + } + + _CACHE_ = {} # (FilePath, Arch) : + + # constructor + def __init__(self, WorkspaceDb): + self.WorkspaceDb = WorkspaceDb + + # key = (FilePath, Arch='COMMON') + def __contains__(self, Key): + FilePath = Key[0] + Arch = 'COMMON' + if len(Key) > 1: + Arch = Key[1] + return (FilePath, Arch) in self._CACHE_ + + # key = (FilePath, Arch='COMMON') + def __getitem__(self, Key): + FilePath = Key[0] + Arch = 'COMMON' + Platform = 'COMMON' + if len(Key) > 1: + Arch = Key[1] + if len(Key) > 2: + Platform = Key[2] + + # if it's generated before, just return the cached one + Key = (FilePath, Arch) + if Key in self._CACHE_: + return self._CACHE_[Key] + + # check file type + Ext = FilePath.Ext.lower() + if Ext not in self._FILE_TYPE_: + return None + FileType = self._FILE_TYPE_[Ext] + if FileType not in self._GENERATOR_: + return None + + # get table for current file + MetaFile = self.WorkspaceDb[FilePath, FileType, self.WorkspaceDb._GlobalMacros] + BuildObject = self._GENERATOR_[FileType]( + FilePath, + MetaFile, + self, + Arch, + Platform, + self.WorkspaceDb._GlobalMacros, + ) + self._CACHE_[Key] = BuildObject + return BuildObject + + # placeholder for file format conversion + class TransformObjectFactory: + def __init__(self, WorkspaceDb): + self.WorkspaceDb = WorkspaceDb + + # key = FilePath, Arch + def __getitem__(self, Key): + pass + + ## Constructor of WorkspaceDatabase + # + # @param DbPath Path of database file + # @param GlobalMacros Global macros used for replacement during file parsing + # @prarm RenewDb=False Create new database file if it's already there + # + def __init__(self, DbPath, GlobalMacros={}, RenewDb=False): + self._GlobalMacros = GlobalMacros + + if DbPath == None or DbPath == '': + DbPath = os.path.normpath(os.path.join(GlobalData.gWorkspace, self._DB_PATH_)) + + # don't create necessary path for db in memory + if DbPath != ':memory:': + DbDir = os.path.split(DbPath)[0] + if not os.path.exists(DbDir): + os.makedirs(DbDir) + + # remove db file in case inconsistency between db and file in file system + if self._CheckWhetherDbNeedRenew(RenewDb, DbPath): + os.remove(DbPath) + + # create db with optimized parameters + self.Conn = sqlite3.connect(DbPath, isolation_level='DEFERRED') + self.Conn.execute("PRAGMA synchronous=OFF") + self.Conn.execute("PRAGMA temp_store=MEMORY") + self.Conn.execute("PRAGMA count_changes=OFF") + self.Conn.execute("PRAGMA cache_size=8192") + #self.Conn.execute("PRAGMA page_size=8192") + + # to avoid non-ascii character conversion issue + self.Conn.text_factory = str + self.Cur = self.Conn.cursor() + + # create table for internal uses + self.TblDataModel = TableDataModel(self.Cur) + self.TblFile = TableFile(self.Cur) + + # conversion object for build or file format conversion purpose + self.BuildObject = WorkspaceDatabase.BuildObjectFactory(self) + self.TransformObject = WorkspaceDatabase.TransformObjectFactory(self) + + ## Check whether workspace database need to be renew. + # The renew reason maybe: + # 1) If user force to renew; + # 2) If user do not force renew, and + # a) If the time of last modified python source is newer than database file; + # b) If the time of last modified frozen executable file is newer than database file; + # + # @param force User force renew database + # @param DbPath The absolute path of workspace database file + # + # @return Bool value for whether need renew workspace databse + # + def _CheckWhetherDbNeedRenew (self, force, DbPath): + # if database does not exist, we need do nothing + if not os.path.exists(DbPath): return False + + # if user force to renew database, then not check whether database is out of date + if force: return True + + # + # Check the time of last modified source file or build.exe + # if is newer than time of database, then database need to be re-created. + # + timeOfToolModified = 0 + if hasattr(sys, "frozen"): + exePath = os.path.abspath(sys.executable) + timeOfToolModified = os.stat(exePath).st_mtime + else: + curPath = os.path.dirname(__file__) # curPath is the path of WorkspaceDatabase.py + rootPath = os.path.split(curPath)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python + if rootPath == "" or rootPath == None: + EdkLogger.verbose("\nFail to find the root path of build.exe or python sources, so can not \ +determine whether database file is out of date!\n") + + # walk the root path of source or build's binary to get the time last modified. + + for root, dirs, files in os.walk (rootPath): + for dir in dirs: + # bypass source control folder + if dir.lower() in [".svn", "_svn", "cvs"]: + dirs.remove(dir) + + for file in files: + ext = os.path.splitext(file)[1] + if ext.lower() == ".py": # only check .py files + fd = os.stat(os.path.join(root, file)) + if timeOfToolModified < fd.st_mtime: + timeOfToolModified = fd.st_mtime + if timeOfToolModified > os.stat(DbPath).st_mtime: + EdkLogger.verbose("\nWorkspace database is out of data!") + return True + + return False + + ## Initialize build database + def InitDatabase(self): + EdkLogger.verbose("\nInitialize build database started ...") + + # + # Create new tables + # + self.TblDataModel.Create(False) + self.TblFile.Create(False) + + # + # Initialize table DataModel + # + self.TblDataModel.InitTable() + EdkLogger.verbose("Initialize build database ... DONE!") + + ## Query a table + # + # @param Table: The instance of the table to be queried + # + def QueryTable(self, Table): + Table.Query() + + ## Close entire database + # + # Commit all first + # Close the connection and cursor + # + def Close(self): + self.Conn.commit() + self.Cur.close() + self.Conn.close() + + ## Get unique file ID for the gvien file + def GetFileId(self, FilePath): + return self.TblFile.GetFileId(FilePath) + + ## Get file type value for the gvien file ID + def GetFileType(self, FileId): + return self.TblFile.GetFileType(FileId) + + ## Get time stamp stored in file table + def GetTimeStamp(self, FileId): + return self.TblFile.GetFileTimeStamp(FileId) + + ## Update time stamp in file table + def SetTimeStamp(self, FileId, TimeStamp): + return self.TblFile.SetFileTimeStamp(FileId, TimeStamp) + + ## Check if a table integrity flag exists or not + def CheckIntegrity(self, TableName): + try: + Result = self.Cur.execute("select min(ID) from %s" % (TableName)).fetchall() + if Result[0][0] != -1: + return False + except: + return False + return True + + ## Compose table name for given file type and file ID + def GetTableName(self, FileType, FileId): + return "_%s_%s" % (FileType, FileId) + + ## Return a temp table containing all content of the given file + # + # @param FileInfo The tuple containing path and type of a file + # + def __getitem__(self, FileInfo): + FilePath, FileType, Macros = FileInfo + if FileType not in self._FILE_TABLE_: + return None + + # flag used to indicate if it's parsed or not + FilePath = str(FilePath) + Parsed = False + FileId = self.GetFileId(FilePath) + if FileId != None: + TimeStamp = os.stat(FilePath)[8] + TableName = self.GetTableName(FileType, FileId) + if TimeStamp != self.GetTimeStamp(FileId): + # update the timestamp in database + self.SetTimeStamp(FileId, TimeStamp) + else: + # if the table exists and is integrity, don't parse it + Parsed = self.CheckIntegrity(TableName) + else: + FileId = self.TblFile.InsertFile(FilePath, FileType) + TableName = self.GetTableName(FileType, FileId) + + FileTable = self._FILE_TABLE_[FileType](self.Cur, TableName, FileId) + FileTable.Create(not Parsed) + Parser = self._FILE_PARSER_[FileType](FilePath, FileType, FileTable, Macros) + # set the "Finished" flag in parser in order to avoid re-parsing (if parsed) + Parser.Finished = Parsed + return Parser + + ## Summarize all packages in the database + def _GetPackageList(self): + PackageList = [] + for Module in self.ModuleList: + for Package in Module.Packages: + if Package not in PackageList: + PackageList.append(Package) + return PackageList + + ## Summarize all platforms in the database + def _GetPlatformList(self): + PlatformList = [] + for PlatformFile in self.TblFile.GetFileList(MODEL_FILE_DSC): + try: + Platform = self.BuildObject[PathClass(PlatformFile), 'COMMON'] + except: + Platform = None + if Platform != None: + PlatformList.append(Platform) + return PlatformList + + ## Summarize all modules in the database + def _GetModuleList(self): + ModuleList = [] + for ModuleFile in self.TblFile.GetFileList(MODEL_FILE_INF): + try: + Module = self.BuildObject[PathClass(ModuleFile), 'COMMON'] + except: + Module = None + if Module != None: + ModuleList.append(Module) + return ModuleList + + PlatformList = property(_GetPlatformList) + PackageList = property(_GetPackageList) + ModuleList = property(_GetModuleList) + +## +# +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +# +if __name__ == '__main__': + pass + diff --git a/BaseTools/Source/Python/Workspace/__init__.py b/BaseTools/Source/Python/Workspace/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/BaseTools/Source/Python/build/__init__.py b/BaseTools/Source/Python/build/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py new file mode 100644 index 0000000000..c92b442615 --- /dev/null +++ b/BaseTools/Source/Python/build/build.py @@ -0,0 +1,1436 @@ +## @file +# build a platform or a module +# +# Copyright (c) 2007, 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 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 re +import sys +import glob +import time +import platform +import traceback + +from threading import * +from optparse import OptionParser +from subprocess import * +from Common import Misc as Utils + +from Common.TargetTxtClassObject import * +from Common.ToolDefClassObject import * +from Common.DataType import * +from AutoGen.AutoGen import * +from Common.BuildToolError import * +from Workspace.WorkspaceDatabase import * + +import Common.EdkLogger +import Common.GlobalData as GlobalData + +# Version and Copyright +VersionNumber = "0.5" +__version__ = "%prog Version " + VersionNumber +__copyright__ = "Copyright (c) 2007, Intel Corporation All rights reserved." + +## standard targets of build command +gSupportedTarget = ['all', 'genc', 'genmake', 'modules', 'libraries', 'fds', 'clean', 'cleanall', 'cleanlib', 'run'] + +## build configuration file +gBuildConfiguration = "Conf/target.txt" +gBuildCacheDir = "Conf/.cache" +gToolsDefinition = "Conf/tools_def.txt" + +## Check environment PATH variable to make sure the specified tool is found +# +# If the tool is found in the PATH, then True is returned +# Otherwise, False is returned +# +def IsToolInPath(tool): + if os.environ.has_key('PATHEXT'): + extns = os.environ['PATHEXT'].split(os.path.pathsep) + else: + extns = ('',) + for pathDir in os.environ['PATH'].split(os.path.pathsep): + for ext in extns: + if os.path.exists(os.path.join(pathDir, tool + ext)): + return True + return False + +## 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/ 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("build", ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found", + ExtraData="WORKSPACE") + + WorkspaceDir = os.path.normcase(os.path.normpath(os.environ["WORKSPACE"])) + if not os.path.exists(WorkspaceDir): + EdkLogger.error("build", FILE_NOT_FOUND, "WORKSPACE doesn't exist", ExtraData="%s" % WorkspaceDir) + elif ' ' in WorkspaceDir: + EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in WORKSPACE path", + ExtraData=WorkspaceDir) + os.environ["WORKSPACE"] = WorkspaceDir + + # + # Check EFI_SOURCE (R8 build convention). EDK_SOURCE will always point to ECP + # + os.environ["ECP_SOURCE"] = os.path.join(WorkspaceDir, GlobalData.gEdkCompatibilityPkg) + if "EFI_SOURCE" not in os.environ: + os.environ["EFI_SOURCE"] = os.environ["ECP_SOURCE"] + if "EDK_SOURCE" not in os.environ: + os.environ["EDK_SOURCE"] = os.environ["ECP_SOURCE"] + + # + # Unify case of characters on case-insensitive systems + # + EfiSourceDir = os.path.normcase(os.path.normpath(os.environ["EFI_SOURCE"])) + EdkSourceDir = os.path.normcase(os.path.normpath(os.environ["EDK_SOURCE"])) + EcpSourceDir = os.path.normcase(os.path.normpath(os.environ["ECP_SOURCE"])) + + os.environ["EFI_SOURCE"] = EfiSourceDir + os.environ["EDK_SOURCE"] = EdkSourceDir + os.environ["ECP_SOURCE"] = EcpSourceDir + os.environ["EDK_TOOLS_PATH"] = os.path.normcase(os.environ["EDK_TOOLS_PATH"]) + + if not os.path.exists(EcpSourceDir): + EdkLogger.verbose("ECP_SOURCE = %s doesn't exist. R8 modules could not be built." % EcpSourceDir) + elif ' ' in EcpSourceDir: + EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in ECP_SOURCE path", + ExtraData=EcpSourceDir) + if not os.path.exists(EdkSourceDir): + if EdkSourceDir == EcpSourceDir: + EdkLogger.verbose("EDK_SOURCE = %s doesn't exist. R8 modules could not be built." % EdkSourceDir) + else: + EdkLogger.error("build", PARAMETER_INVALID, "EDK_SOURCE does not exist", + ExtraData=EdkSourceDir) + elif ' ' in EdkSourceDir: + EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in EDK_SOURCE path", + ExtraData=EdkSourceDir) + if not os.path.exists(EfiSourceDir): + if EfiSourceDir == EcpSourceDir: + EdkLogger.verbose("EFI_SOURCE = %s doesn't exist. R8 modules could not be built." % EfiSourceDir) + else: + EdkLogger.error("build", PARAMETER_INVALID, "EFI_SOURCE does not exist", + ExtraData=EfiSourceDir) + elif ' ' in EfiSourceDir: + EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in EFI_SOURCE path", + ExtraData=EfiSourceDir) + + # change absolute path to relative path to WORKSPACE + if EfiSourceDir.upper().find(WorkspaceDir.upper()) != 0: + EdkLogger.error("build", PARAMETER_INVALID, "EFI_SOURCE is not under WORKSPACE", + ExtraData="WORKSPACE = %s\n EFI_SOURCE = %s" % (WorkspaceDir, EfiSourceDir)) + if EdkSourceDir.upper().find(WorkspaceDir.upper()) != 0: + EdkLogger.error("build", PARAMETER_INVALID, "EDK_SOURCE is not under WORKSPACE", + ExtraData="WORKSPACE = %s\n EDK_SOURCE = %s" % (WorkspaceDir, EdkSourceDir)) + if EcpSourceDir.upper().find(WorkspaceDir.upper()) != 0: + EdkLogger.error("build", PARAMETER_INVALID, "ECP_SOURCE is not under WORKSPACE", + ExtraData="WORKSPACE = %s\n ECP_SOURCE = %s" % (WorkspaceDir, EcpSourceDir)) + + # check EDK_TOOLS_PATH + if "EDK_TOOLS_PATH" not in os.environ: + EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found", + ExtraData="EDK_TOOLS_PATH") + + # check PATH + if "PATH" not in os.environ: + EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found", + ExtraData="PATH") + + # for macro replacement in R9 DSC/DEC/INF file + GlobalData.gGlobalDefines["WORKSPACE"] = "" + + # for macro replacement in R8 INF file + GlobalData.gGlobalDefines["EFI_SOURCE"] = EfiSourceDir + GlobalData.gGlobalDefines["EDK_SOURCE"] = EdkSourceDir + + GlobalData.gWorkspace = WorkspaceDir + GlobalData.gEfiSource = EfiSourceDir + GlobalData.gEdkSource = EdkSourceDir + GlobalData.gEcpSource = EcpSourceDir + +## Get normalized file path +# +# Convert the path to be local format, and remove the WORKSPACE path at the +# beginning if the file path is given in full path. +# +# @param FilePath File path to be normalized +# @param Workspace Workspace path which the FilePath will be checked against +# +# @retval string The normalized file path +# +def NormFile(FilePath, Workspace): + # check if the path is absolute or relative + if os.path.isabs(FilePath): + FileFullPath = os.path.normpath(FilePath) + else: + FileFullPath = os.path.normpath(os.path.join(Workspace, FilePath)) + + # check if the file path exists or not + if not os.path.isfile(FileFullPath): + EdkLogger.error("build", FILE_NOT_FOUND, ExtraData="\t%s (Please give file in absolute path or relative to WORKSPACE)" % FileFullPath) + + # remove workspace directory from the beginning part of the file path + if Workspace[-1] in ["\\", "/"]: + return FileFullPath[len(Workspace):] + else: + return FileFullPath[(len(Workspace) + 1):] + +## Get the output of an external program +# +# This is the entrance method of thread reading output of an external program and +# putting them in STDOUT/STDERR of current program. +# +# @param From The stream message read from +# @param To The stream message put on +# @param ExitFlag The flag used to indicate stopping reading +# +def ReadMessage(From, To, ExitFlag): + while True: + # read one line a time + Line = From.readline() + # empty string means "end" + if Line != None and Line != "": + To(Line.rstrip()) + else: + break + if ExitFlag.isSet(): + break + +## Launch an external program +# +# This method will call subprocess.Popen to execute an external program with +# given options in specified directory. Because of the dead-lock issue during +# redirecting output of the external program, threads are used to to do the +# redirection work. +# +# @param Command A list or string containing the call of the program +# @param WorkingDir The directory in which the program will be running +# +def LaunchCommand(Command, WorkingDir): + # if working directory doesn't exist, Popen() will raise an exception + if not os.path.isdir(WorkingDir): + EdkLogger.error("build", FILE_NOT_FOUND, ExtraData=WorkingDir) + + Proc = None + EndOfProcedure = None + try: + # launch the command + Proc = Popen(Command, stdout=PIPE, stderr=PIPE, env=os.environ, cwd=WorkingDir, bufsize=-1) + + # launch two threads to read the STDOUT and STDERR + EndOfProcedure = Event() + EndOfProcedure.clear() + if Proc.stdout: + StdOutThread = Thread(target=ReadMessage, args=(Proc.stdout, EdkLogger.info, EndOfProcedure)) + StdOutThread.setName("STDOUT-Redirector") + StdOutThread.setDaemon(False) + StdOutThread.start() + + if Proc.stderr: + StdErrThread = Thread(target=ReadMessage, args=(Proc.stderr, EdkLogger.quiet, EndOfProcedure)) + StdErrThread.setName("STDERR-Redirector") + StdErrThread.setDaemon(False) + StdErrThread.start() + + # waiting for program exit + Proc.wait() + except: # in case of aborting + # terminate the threads redirecting the program output + if EndOfProcedure != None: + EndOfProcedure.set() + if Proc == None: + if type(Command) != type(""): + Command = " ".join(Command) + EdkLogger.error("build", COMMAND_FAILURE, "Failed to start command", ExtraData="%s [%s]" % (Command, WorkingDir)) + + if Proc.stdout: + StdOutThread.join() + if Proc.stderr: + StdErrThread.join() + + # check the return code of the program + if Proc.returncode != 0: + if type(Command) != type(""): + Command = " ".join(Command) + EdkLogger.error("build", COMMAND_FAILURE, ExtraData="%s [%s]" % (Command, WorkingDir)) + +## The smallest unit that can be built in multi-thread build mode +# +# This is the base class of build unit. The "Obj" parameter must provide +# __str__(), __eq__() and __hash__() methods. Otherwise there could be build units +# missing build. +# +# Currently the "Obj" should be only ModuleAutoGen or PlatformAutoGen objects. +# +class BuildUnit: + ## The constructor + # + # @param self The object pointer + # @param Obj The object the build is working on + # @param Target The build target name, one of gSupportedTarget + # @param Dependency The BuildUnit(s) which must be completed in advance + # @param WorkingDir The directory build command starts in + # + def __init__(self, Obj, BuildCommand, Target, Dependency, WorkingDir="."): + self.BuildObject = Obj + self.Dependency = Dependency + self.WorkingDir = WorkingDir + self.Target = Target + self.BuildCommand = BuildCommand + if BuildCommand == None or len(BuildCommand) == 0: + EdkLogger.error("build", OPTION_MISSING, "No build command found for", + ExtraData=str(Obj)) + + ## str() method + # + # It just returns the string representaion of self.BuildObject + # + # @param self The object pointer + # + def __str__(self): + return str(self.BuildObject) + + ## "==" operator method + # + # It just compares self.BuildObject with "Other". So self.BuildObject must + # provide its own __eq__() method. + # + # @param self The object pointer + # @param Other The other BuildUnit object compared to + # + def __eq__(self, Other): + return Other != None and self.BuildObject == Other.BuildObject \ + and self.BuildObject.Arch == Other.BuildObject.Arch + + ## hash() method + # + # It just returns the hash value of self.BuildObject which must be hashable. + # + # @param self The object pointer + # + def __hash__(self): + return hash(self.BuildObject) + hash(self.BuildObject.Arch) + + def __repr__(self): + return repr(self.BuildObject) + +## The smallest module unit that can be built by nmake/make command in multi-thread build mode +# +# This class is for module build by nmake/make build system. The "Obj" parameter +# must provide __str__(), __eq__() and __hash__() methods. Otherwise there could +# be make units missing build. +# +# Currently the "Obj" should be only ModuleAutoGen object. +# +class ModuleMakeUnit(BuildUnit): + ## The constructor + # + # @param self The object pointer + # @param Obj The ModuleAutoGen object the build is working on + # @param Target The build target name, one of gSupportedTarget + # + def __init__(self, Obj, Target): + Dependency = [ModuleMakeUnit(La, Target) for La in Obj.LibraryAutoGenList] + BuildUnit.__init__(self, Obj, Obj.BuildCommand, Target, Dependency, Obj.MakeFileDir) + if Target in [None, "", "all"]: + self.Target = "tbuild" + +## The smallest platform unit that can be built by nmake/make command in multi-thread build mode +# +# This class is for platform build by nmake/make build system. The "Obj" parameter +# must provide __str__(), __eq__() and __hash__() methods. Otherwise there could +# be make units missing build. +# +# Currently the "Obj" should be only PlatformAutoGen object. +# +class PlatformMakeUnit(BuildUnit): + ## The constructor + # + # @param self The object pointer + # @param Obj The PlatformAutoGen object the build is working on + # @param Target The build target name, one of gSupportedTarget + # + def __init__(self, Obj, Target): + Dependency = [ModuleMakeUnit(Lib, Target) for Lib in self.BuildObject.LibraryAutoGenList] + Dependency.extend([ModuleMakeUnit(Mod, Target) for Mod in self.BuildObject.ModuleAutoGenList]) + BuildUnit.__init__(self, Obj, Obj.BuildCommand, Target, Dependency, Obj.MakeFileDir) + +## The class representing the task of a module build or platform build +# +# This class manages the build tasks in multi-thread build mode. Its jobs include +# scheduling thread running, catching thread error, monitor the thread status, etc. +# +class BuildTask: + # queue for tasks waiting for schedule + _PendingQueue = sdict() + _PendingQueueLock = threading.Lock() + + # queue for tasks ready for running + _ReadyQueue = sdict() + _ReadyQueueLock = threading.Lock() + + # queue for run tasks + _RunningQueue = sdict() + _RunningQueueLock = threading.Lock() + + # queue containing all build tasks, in case duplicate build + _TaskQueue = sdict() + + # flag indicating error occurs in a running thread + _ErrorFlag = threading.Event() + _ErrorFlag.clear() + _ErrorMessage = "" + + # BoundedSemaphore object used to control the number of running threads + _Thread = None + + # flag indicating if the scheduler is started or not + _SchedulerStopped = threading.Event() + _SchedulerStopped.set() + + ## Start the task scheduler thread + # + # @param MaxThreadNumber The maximum thread number + # @param ExitFlag Flag used to end the scheduler + # + @staticmethod + def StartScheduler(MaxThreadNumber, ExitFlag): + SchedulerThread = Thread(target=BuildTask.Scheduler, args=(MaxThreadNumber, ExitFlag)) + SchedulerThread.setName("Build-Task-Scheduler") + SchedulerThread.setDaemon(False) + SchedulerThread.start() + # wait for the scheduler to be started, especially useful in Linux + while not BuildTask.IsOnGoing(): + time.sleep(0.01) + + ## Scheduler method + # + # @param MaxThreadNumber The maximum thread number + # @param ExitFlag Flag used to end the scheduler + # + @staticmethod + def Scheduler(MaxThreadNumber, ExitFlag): + BuildTask._SchedulerStopped.clear() + try: + # use BoundedSemaphore to control the maximum running threads + BuildTask._Thread = BoundedSemaphore(MaxThreadNumber) + # + # scheduling loop, which will exits when no pending/ready task and + # indicated to do so, or there's error in running thread + # + while (len(BuildTask._PendingQueue) > 0 or len(BuildTask._ReadyQueue) > 0 \ + or not ExitFlag.isSet()) and not BuildTask._ErrorFlag.isSet(): + EdkLogger.debug(EdkLogger.DEBUG_8, "Pending Queue (%d), Ready Queue (%d)" + % (len(BuildTask._PendingQueue), len(BuildTask._ReadyQueue))) + + # get all pending tasks + BuildTask._PendingQueueLock.acquire() + BuildObjectList = BuildTask._PendingQueue.keys() + # + # check if their dependency is resolved, and if true, move them + # into ready queue + # + for BuildObject in BuildObjectList: + Bt = BuildTask._PendingQueue[BuildObject] + if Bt.IsReady(): + BuildTask._ReadyQueue[BuildObject] = BuildTask._PendingQueue.pop(BuildObject) + BuildTask._PendingQueueLock.release() + + # launch build thread until the maximum number of threads is reached + while not BuildTask._ErrorFlag.isSet(): + # empty ready queue, do nothing further + if len(BuildTask._ReadyQueue) == 0: + break + + # wait for active thread(s) exit + BuildTask._Thread.acquire(True) + + # start a new build thread + Bo = BuildTask._ReadyQueue.keys()[0] + Bt = BuildTask._ReadyQueue.pop(Bo) + + # move into running queue + BuildTask._RunningQueueLock.acquire() + BuildTask._RunningQueue[Bo] = Bt + BuildTask._RunningQueueLock.release() + + Bt.Start() + # avoid tense loop + time.sleep(0.01) + + # avoid tense loop + time.sleep(0.01) + + # wait for all running threads exit + if BuildTask._ErrorFlag.isSet(): + EdkLogger.quiet("\nWaiting for all build threads exit...") + # while not BuildTask._ErrorFlag.isSet() and \ + while len(BuildTask._RunningQueue) > 0: + EdkLogger.verbose("Waiting for thread ending...(%d)" % len(BuildTask._RunningQueue)) + EdkLogger.debug(EdkLogger.DEBUG_8, "Threads [%s]" % ", ".join([Th.getName() for Th in threading.enumerate()])) + # avoid tense loop + time.sleep(0.1) + except BaseException, X: + # + # TRICK: hide the output of threads left runing, so that the user can + # catch the error message easily + # + EdkLogger.SetLevel(EdkLogger.ERROR) + BuildTask._ErrorFlag.set() + BuildTask._ErrorMessage = "build thread scheduler error\n\t%s" % str(X) + + BuildTask._PendingQueue.clear() + BuildTask._ReadyQueue.clear() + BuildTask._RunningQueue.clear() + BuildTask._TaskQueue.clear() + BuildTask._SchedulerStopped.set() + + ## Wait for all running method exit + # + @staticmethod + def WaitForComplete(): + BuildTask._SchedulerStopped.wait() + + ## Check if the scheduler is running or not + # + @staticmethod + def IsOnGoing(): + return not BuildTask._SchedulerStopped.isSet() + + ## Abort the build + @staticmethod + def Abort(): + if BuildTask.IsOnGoing(): + BuildTask._ErrorFlag.set() + BuildTask.WaitForComplete() + + ## Check if there's error in running thread + # + # Since the main thread cannot catch exceptions in other thread, we have to + # use threading.Event to communicate this formation to main thread. + # + @staticmethod + def HasError(): + return BuildTask._ErrorFlag.isSet() + + ## Get error message in running thread + # + # Since the main thread cannot catch exceptions in other thread, we have to + # use a static variable to communicate this message to main thread. + # + @staticmethod + def GetErrorMessage(): + return BuildTask._ErrorMessage + + ## Factory method to create a BuildTask object + # + # This method will check if a module is building or has been built. And if + # true, just return the associated BuildTask object in the _TaskQueue. If + # not, create and return a new BuildTask object. The new BuildTask object + # will be appended to the _PendingQueue for scheduling later. + # + # @param BuildItem A BuildUnit object representing a build object + # @param Dependency The dependent build object of BuildItem + # + @staticmethod + def New(BuildItem, Dependency=None): + if BuildItem in BuildTask._TaskQueue: + Bt = BuildTask._TaskQueue[BuildItem] + return Bt + + Bt = BuildTask() + Bt._Init(BuildItem, Dependency) + BuildTask._TaskQueue[BuildItem] = Bt + + BuildTask._PendingQueueLock.acquire() + BuildTask._PendingQueue[BuildItem] = Bt + BuildTask._PendingQueueLock.release() + + return Bt + + ## The real constructor of BuildTask + # + # @param BuildItem A BuildUnit object representing a build object + # @param Dependency The dependent build object of BuildItem + # + def _Init(self, BuildItem, Dependency=None): + self.BuildItem = BuildItem + + self.DependencyList = [] + if Dependency == None: + Dependency = BuildItem.Dependency + else: + Dependency.extend(BuildItem.Dependency) + self.AddDependency(Dependency) + # flag indicating build completes, used to avoid unnecessary re-build + self.CompleteFlag = False + + ## Check if all dependent build tasks are completed or not + # + def IsReady(self): + ReadyFlag = True + for Dep in self.DependencyList: + if Dep.CompleteFlag == True: + continue + ReadyFlag = False + break + + return ReadyFlag + + ## Add dependent build task + # + # @param Dependency The list of dependent build objects + # + def AddDependency(self, Dependency): + for Dep in Dependency: + self.DependencyList.append(BuildTask.New(Dep)) # BuildTask list + + ## The thread wrapper of LaunchCommand function + # + # @param Command A list or string contains the call of the command + # @param WorkingDir The directory in which the program will be running + # + def _CommandThread(self, Command, WorkingDir): + try: + LaunchCommand(Command, WorkingDir) + self.CompleteFlag = True + except: + # + # TRICK: hide the output of threads left runing, so that the user can + # catch the error message easily + # + if not BuildTask._ErrorFlag.isSet(): + GlobalData.gBuildingModule = "%s [%s, %s, %s]" % (str(self.BuildItem.BuildObject), + self.BuildItem.BuildObject.Arch, + self.BuildItem.BuildObject.ToolChain, + self.BuildItem.BuildObject.BuildTarget + ) + EdkLogger.SetLevel(EdkLogger.ERROR) + BuildTask._ErrorFlag.set() + BuildTask._ErrorMessage = "%s broken\n %s [%s]" % \ + (threading.currentThread().getName(), Command, WorkingDir) + # indicate there's a thread is available for another build task + BuildTask._RunningQueueLock.acquire() + BuildTask._RunningQueue.pop(self.BuildItem) + BuildTask._RunningQueueLock.release() + BuildTask._Thread.release() + + ## Start build task thread + # + def Start(self): + EdkLogger.quiet("Building ... %s" % repr(self.BuildItem)) + Command = self.BuildItem.BuildCommand + [self.BuildItem.Target] + self.BuildTread = Thread(target=self._CommandThread, args=(Command, self.BuildItem.WorkingDir)) + self.BuildTread.setName("build thread") + self.BuildTread.setDaemon(False) + self.BuildTread.start() + +## The class implementing the EDK2 build process +# +# The build process includes: +# 1. Load configuration from target.txt and tools_def.txt in $(WORKSPACE)/Conf +# 2. Parse DSC file of active platform +# 3. Parse FDF file if any +# 4. Establish build database, including parse all other files (module, package) +# 5. Create AutoGen files (C code file, depex file, makefile) if necessary +# 6. Call build command +# +class Build(): + ## Constructor + # + # Constructor will load all necessary configurations, parse platform, modules + # and packages and the establish a database for AutoGen. + # + # @param Target The build command target, one of gSupportedTarget + # @param WorkspaceDir The directory of workspace + # @param Platform The DSC file of active platform + # @param Module The INF file of active module, if any + # @param Arch The Arch list of platform or module + # @param ToolChain The name list of toolchain + # @param BuildTarget The "DEBUG" or "RELEASE" build + # @param FlashDefinition The FDF file of active platform + # @param FdList=[] The FD names to be individually built + # @param FvList=[] The FV names to be individually built + # @param MakefileType The type of makefile (for MSFT make or GNU make) + # @param SilentMode Indicate multi-thread build mode + # @param ThreadNumber The maximum number of thread if in multi-thread build mode + # @param SkipAutoGen Skip AutoGen step + # @param Reparse Re-parse all meta files + # @param SkuId SKU id from command line + # + def __init__(self, Target, WorkspaceDir, Platform, Module, Arch, ToolChain, + BuildTarget, FlashDefinition, FdList=[], FvList=[], + MakefileType="nmake", SilentMode=False, ThreadNumber=2, + SkipAutoGen=False, Reparse=False, SkuId=None): + + self.WorkspaceDir = WorkspaceDir + self.Target = Target + self.PlatformFile = Platform + self.ModuleFile = Module + self.ArchList = Arch + self.ToolChainList = ToolChain + self.BuildTargetList= BuildTarget + self.Fdf = FlashDefinition + self.FdList = FdList + self.FvList = FvList + self.MakefileType = MakefileType + self.SilentMode = SilentMode + self.ThreadNumber = ThreadNumber + self.SkipAutoGen = SkipAutoGen + self.Reparse = Reparse + self.SkuId = SkuId + self.SpawnMode = True + + self.TargetTxt = TargetTxtClassObject() + self.ToolDef = ToolDefClassObject() + #self.Db = WorkspaceDatabase(None, GlobalData.gGlobalDefines, self.Reparse) + self.Db = WorkspaceDatabase(None, {}, self.Reparse) + self.BuildDatabase = self.Db.BuildObject + self.Platform = None + + # print dot charater during doing some time-consuming work + self.Progress = Utils.Progressor() + + # parse target.txt, tools_def.txt, and platform file + #self.RestoreBuildData() + self.LoadConfiguration() + self.InitBuild() + + # print current build environment and configuration + EdkLogger.quiet("%-24s = %s" % ("WORKSPACE", os.environ["WORKSPACE"])) + EdkLogger.quiet("%-24s = %s" % ("ECP_SOURCE", os.environ["ECP_SOURCE"])) + EdkLogger.quiet("%-24s = %s" % ("EDK_SOURCE", os.environ["EDK_SOURCE"])) + EdkLogger.quiet("%-24s = %s" % ("EFI_SOURCE", os.environ["EFI_SOURCE"])) + EdkLogger.quiet("%-24s = %s" % ("EDK_TOOLS_PATH", os.environ["EDK_TOOLS_PATH"])) + + EdkLogger.info('\n%-24s = %s' % ("TARGET_ARCH", ' '.join(self.ArchList))) + EdkLogger.info('%-24s = %s' % ("TARGET", ' '.join(self.BuildTargetList))) + EdkLogger.info('%-24s = %s' % ("TOOL_CHAIN_TAG", ' '.join(self.ToolChainList))) + + EdkLogger.info('\n%-24s = %s' % ("Active Platform", self.PlatformFile)) + + if self.Fdf != None and self.Fdf != "": + EdkLogger.info('%-24s = %s' % ("Flash Image Definition", self.Fdf)) + + if self.ModuleFile != None and self.ModuleFile != "": + EdkLogger.info('%-24s = %s' % ("Active Module", self.ModuleFile)) + + os.chdir(self.WorkspaceDir) + self.Progress.Start("\nProcessing meta-data") + + ## Load configuration + # + # This method will parse target.txt and get the build configurations. + # + def LoadConfiguration(self): + # + # Check target.txt and tools_def.txt and Init them + # + BuildConfigurationFile = os.path.normpath(os.path.join(self.WorkspaceDir, gBuildConfiguration)) + if os.path.isfile(BuildConfigurationFile) == True: + StatusCode = self.TargetTxt.LoadTargetTxtFile(BuildConfigurationFile) + + ToolDefinitionFile = self.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF] + if ToolDefinitionFile == '': + ToolDefinitionFile = gToolsDefinition + ToolDefinitionFile = os.path.normpath(os.path.join(self.WorkspaceDir, ToolDefinitionFile)) + if os.path.isfile(ToolDefinitionFile) == True: + StatusCode = self.ToolDef.LoadToolDefFile(ToolDefinitionFile) + else: + EdkLogger.error("build", FILE_NOT_FOUND, ExtraData=ToolDefinitionFile) + else: + EdkLogger.error("build", FILE_NOT_FOUND, ExtraData=BuildConfigurationFile) + + # if no ARCH given in command line, get it from target.txt + if self.ArchList == None or len(self.ArchList) == 0: + self.ArchList = self.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TARGET_ARCH] + + # if no build target given in command line, get it from target.txt + if self.BuildTargetList == None or len(self.BuildTargetList) == 0: + self.BuildTargetList = self.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TARGET] + + # if no tool chain given in command line, get it from target.txt + if self.ToolChainList == None or len(self.ToolChainList) == 0: + self.ToolChainList = self.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_TAG] + if self.ToolChainList == None or len(self.ToolChainList) == 0: + EdkLogger.error("build", RESOURCE_NOT_AVAILABLE, ExtraData="No toolchain given. Don't know how to build.\n") + + # check if the tool chains are defined or not + NewToolChainList = [] + for ToolChain in self.ToolChainList: + if ToolChain not in self.ToolDef.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG]: + EdkLogger.warn("build", "Tool chain [%s] is not defined" % ToolChain) + else: + NewToolChainList.append(ToolChain) + # if no tool chain available, break the build + if len(NewToolChainList) == 0: + EdkLogger.error("build", RESOURCE_NOT_AVAILABLE, + ExtraData="[%s] not defined. No toolchain available for build!\n" % ", ".join(self.ToolChainList)) + else: + self.ToolChainList = NewToolChainList + + if self.ThreadNumber == None: + self.ThreadNumber = self.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER] + if self.ThreadNumber == '': + self.ThreadNumber = 0 + else: + self.ThreadNumber = int(self.ThreadNumber, 0) + + if self.ThreadNumber == 0: + self.ThreadNumber = 1 + + if not self.PlatformFile: + PlatformFile = self.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_ACTIVE_PLATFORM] + if not PlatformFile: + # Try to find one in current directory + WorkingDirectory = os.getcwd() + FileList = glob.glob(os.path.normpath(os.path.join(WorkingDirectory, '*.dsc'))) + FileNum = len(FileList) + if FileNum >= 2: + EdkLogger.error("build", OPTION_MISSING, + ExtraData="There are %d DSC files in %s. Use '-p' to specify one.\n" % (FileNum, WorkingDirectory)) + elif FileNum == 1: + PlatformFile = FileList[0] + else: + EdkLogger.error("build", RESOURCE_NOT_AVAILABLE, + ExtraData="No active platform specified in target.txt or command line! Nothing can be built.\n") + + self.PlatformFile = PathClass(NormFile(PlatformFile, self.WorkspaceDir), self.WorkspaceDir) + ErrorCode, ErrorInfo = self.PlatformFile.Validate(".dsc", False) + if ErrorCode != 0: + EdkLogger.error("build", ErrorCode, ExtraData=ErrorInfo) + + ## Initialize build configuration + # + # This method will parse DSC file and merge the configurations from + # command line and target.txt, then get the final build configurations. + # + def InitBuild(self): + ErrorCode, ErrorInfo = self.PlatformFile.Validate(".dsc") + if ErrorCode != 0: + EdkLogger.error("build", ErrorCode, ExtraData=ErrorInfo) + + # create metafile database + self.Db.InitDatabase() + + # we need information in platform description file to determine how to build + self.Platform = self.BuildDatabase[self.PlatformFile, 'COMMON'] + if not self.Fdf: + self.Fdf = self.Platform.FlashDefinition + + if self.SkuId == None or self.SkuId == '': + self.SkuId = self.Platform.SkuName + + # check FD/FV build target + if self.Fdf == None or self.Fdf == "": + if self.FdList != []: + EdkLogger.info("No flash definition file found. FD [%s] will be ignored." % " ".join(self.FdList)) + self.FdList = [] + if self.FvList != []: + EdkLogger.info("No flash definition file found. FV [%s] will be ignored." % " ".join(self.FvList)) + self.FvList = [] + else: + FdfParserObj = FdfParser(str(self.Fdf)) + FdfParserObj.ParseFile() + for fvname in self.FvList: + if fvname.upper() not in FdfParserObj.Profile.FvDict.keys(): + EdkLogger.error("build", OPTION_VALUE_INVALID, + "No such an FV in FDF file: %s" % fvname) + + # + # Merge Arch + # + if self.ArchList == None or len(self.ArchList) == 0: + ArchList = set(self.Platform.SupArchList) + else: + ArchList = set(self.ArchList) & set(self.Platform.SupArchList) + if len(ArchList) == 0: + EdkLogger.error("build", PARAMETER_INVALID, + ExtraData = "Active platform supports [%s] only, but [%s] is given." + % (" ".join(self.Platform.SupArchList), " ".join(self.ArchList))) + elif len(ArchList) != len(self.ArchList): + SkippedArchList = set(self.ArchList).symmetric_difference(set(self.Platform.SupArchList)) + EdkLogger.verbose("\nArch [%s] is ignored because active platform supports [%s] but [%s] is specified !" + % (" ".join(SkippedArchList), " ".join(self.Platform.SupArchList), " ".join(self.ArchList))) + self.ArchList = tuple(ArchList) + + # Merge build target + if self.BuildTargetList == None or len(self.BuildTargetList) == 0: + BuildTargetList = self.Platform.BuildTargets + else: + BuildTargetList = list(set(self.BuildTargetList) & set(self.Platform.BuildTargets)) + if BuildTargetList == []: + EdkLogger.error("build", PARAMETER_INVALID, "Active platform only supports [%s], but [%s] is given" + % (" ".join(self.Platform.BuildTargets), " ".join(self.BuildTargetList))) + self.BuildTargetList = BuildTargetList + + ## Build a module or platform + # + # Create autogen code and makfile for a module or platform, and the launch + # "make" command to build it + # + # @param Target The target of build command + # @param Platform The platform file + # @param Module The module file + # @param BuildTarget The name of build target, one of "DEBUG", "RELEASE" + # @param ToolChain The name of toolchain to build + # @param Arch The arch of the module/platform + # @param CreateDepModuleCodeFile Flag used to indicate creating code + # for dependent modules/Libraries + # @param CreateDepModuleMakeFile Flag used to indicate creating makefile + # for dependent modules/Libraries + # + def _Build(self, Target, AutoGenObject, CreateDepsCodeFile=True, CreateDepsMakeFile=True): + if AutoGenObject == None: + return False + + # skip file generation for cleanxxx targets, run and fds target + if Target not in ['clean', 'cleanlib', 'cleanall', 'run', 'fds']: + # for target which must generate AutoGen code and makefile + if not self.SkipAutoGen or Target == 'genc': + self.Progress.Start("Generating code") + AutoGenObject.CreateCodeFile(CreateDepsCodeFile) + self.Progress.Stop("done!") + if Target == "genc": + return True + + if not self.SkipAutoGen or Target == 'genmake': + self.Progress.Start("Generating makefile") + AutoGenObject.CreateMakeFile(CreateDepsMakeFile) + self.Progress.Stop("done!") + if Target == "genmake": + return True + else: + # always recreate top/platform makefile when clean, just in case of inconsistency + AutoGenObject.CreateCodeFile(False) + AutoGenObject.CreateMakeFile(False) + + if EdkLogger.GetLevel() == EdkLogger.QUIET: + EdkLogger.quiet("Building ... %s" % repr(AutoGenObject)) + + BuildCommand = AutoGenObject.BuildCommand + if BuildCommand == None or len(BuildCommand) == 0: + EdkLogger.error("build", OPTION_MISSING, ExtraData="No MAKE command found for [%s, %s, %s]" % Key) + + BuildCommand = BuildCommand + [Target] + LaunchCommand(BuildCommand, AutoGenObject.MakeFileDir) + if Target == 'cleanall': + try: + #os.rmdir(AutoGenObject.BuildDir) + RemoveDirectory(AutoGenObject.BuildDir, True) + except WindowsError, X: + EdkLogger.error("build", FILE_DELETE_FAILURE, ExtraData=str(X)) + return True + + ## Build active platform for different build targets and different tool chains + # + def _BuildPlatform(self): + for BuildTarget in self.BuildTargetList: + for ToolChain in self.ToolChainList: + Wa = WorkspaceAutoGen( + self.WorkspaceDir, + self.Platform, + BuildTarget, + ToolChain, + self.ArchList, + self.BuildDatabase, + self.TargetTxt, + self.ToolDef, + self.Fdf, + self.FdList, + self.FvList, + self.SkuId + ) + self.Progress.Stop("done!") + self._Build(self.Target, Wa) + + ## Build active module for different build targets, different tool chains and different archs + # + def _BuildModule(self): + for BuildTarget in self.BuildTargetList: + for ToolChain in self.ToolChainList: + # + # module build needs platform build information, so get platform + # AutoGen first + # + Wa = WorkspaceAutoGen( + self.WorkspaceDir, + self.Platform, + BuildTarget, + ToolChain, + self.ArchList, + self.BuildDatabase, + self.TargetTxt, + self.ToolDef, + self.Fdf, + self.FdList, + self.FvList, + self.SkuId + ) + Wa.CreateMakeFile(False) + self.Progress.Stop("done!") + MaList = [] + for Arch in self.ArchList: + Ma = ModuleAutoGen(Wa, self.ModuleFile, BuildTarget, ToolChain, Arch, self.PlatformFile) + if Ma == None: continue + MaList.append(Ma) + self._Build(self.Target, Ma) + if MaList == []: + EdkLogger.error( + 'build', + BUILD_ERROR, + "Module for [%s] is not a component of active platform."\ + " Please make sure that the ARCH and inf file path are"\ + " given in the same as in [%s]" %\ + (', '.join(self.ArchList), self.Platform), + ExtraData=self.ModuleFile + ) + + ## Build a platform in multi-thread mode + # + def _MultiThreadBuildPlatform(self): + for BuildTarget in self.BuildTargetList: + for ToolChain in self.ToolChainList: + Wa = WorkspaceAutoGen( + self.WorkspaceDir, + self.Platform, + BuildTarget, + ToolChain, + self.ArchList, + self.BuildDatabase, + self.TargetTxt, + self.ToolDef, + self.Fdf, + self.FdList, + self.FvList, + self.SkuId + ) + Wa.CreateMakeFile(False) + + # multi-thread exit flag + ExitFlag = threading.Event() + ExitFlag.clear() + for Arch in self.ArchList: + Pa = PlatformAutoGen(Wa, self.PlatformFile, BuildTarget, ToolChain, Arch) + if Pa == None: + continue + for Module in Pa.Platform.Modules: + # Get ModuleAutoGen object to generate C code file and makefile + Ma = ModuleAutoGen(Wa, Module, BuildTarget, ToolChain, Arch, self.PlatformFile) + if Ma == None: + continue + # Not to auto-gen for targets 'clean', 'cleanlib', 'cleanall', 'run', 'fds' + if self.Target not in ['clean', 'cleanlib', 'cleanall', 'run', 'fds']: + # for target which must generate AutoGen code and makefile + if not self.SkipAutoGen or self.Target == 'genc': + Ma.CreateCodeFile(True) + if self.Target == "genc": + continue + + if not self.SkipAutoGen or self.Target == 'genmake': + Ma.CreateMakeFile(True) + if self.Target == "genmake": + continue + self.Progress.Stop("done!") + # Generate build task for the module + Bt = BuildTask.New(ModuleMakeUnit(Ma, self.Target)) + # Break build if any build thread has error + if BuildTask.HasError(): + # we need a full version of makefile for platform + ExitFlag.set() + BuildTask.WaitForComplete() + Pa.CreateMakeFile(False) + EdkLogger.error("build", BUILD_ERROR, "Failed to build module", ExtraData=GlobalData.gBuildingModule) + # Start task scheduler + if not BuildTask.IsOnGoing(): + BuildTask.StartScheduler(self.ThreadNumber, ExitFlag) + + # in case there's an interruption. we need a full version of makefile for platform + Pa.CreateMakeFile(False) + if BuildTask.HasError(): + EdkLogger.error("build", BUILD_ERROR, "Failed to build module", ExtraData=GlobalData.gBuildingModule) + + # + # All modules have been put in build tasks queue. Tell task scheduler + # to exit if all tasks are completed + # + ExitFlag.set() + BuildTask.WaitForComplete() + + # + # Check for build error, and raise exception if one + # has been signaled. + # + if BuildTask.HasError(): + EdkLogger.error("build", BUILD_ERROR, "Failed to build module", ExtraData=GlobalData.gBuildingModule) + + # Generate FD image if there's a FDF file found + if self.Fdf != '' and self.Target in ["", "all", "fds"]: + LaunchCommand(Wa.BuildCommand + ["fds"], Wa.MakeFileDir) + + ## Generate GuidedSectionTools.txt in the FV directories. + # + def CreateGuidedSectionToolsFile(self): + for Arch in self.ArchList: + for BuildTarget in self.BuildTargetList: + for ToolChain in self.ToolChainList: + FvDir = os.path.join( + self.WorkspaceDir, + self.Platform.OutputDirectory, + '_'.join((BuildTarget, ToolChain)), + 'FV' + ) + if not os.path.exists(FvDir): + continue + # Build up the list of supported architectures for this build + prefix = '%s_%s_%s_' % (BuildTarget, ToolChain, Arch) + + # Look through the tool definitions for GUIDed tools + guidAttribs = [] + for (attrib, value) in self.ToolDef.ToolsDefTxtDictionary.iteritems(): + if attrib.upper().endswith('_GUID'): + split = attrib.split('_') + thisPrefix = '_'.join(split[0:3]) + '_' + if thisPrefix == prefix: + guid = self.ToolDef.ToolsDefTxtDictionary[attrib] + guid = guid.lower() + toolName = split[3] + path = '_'.join(split[0:4]) + '_PATH' + path = self.ToolDef.ToolsDefTxtDictionary[path] + path = self.GetFullPathOfTool(path) + guidAttribs.append((guid, toolName, path)) + + # Write out GuidedSecTools.txt + toolsFile = os.path.join(FvDir, 'GuidedSectionTools.txt') + toolsFile = open(toolsFile, 'wt') + for guidedSectionTool in guidAttribs: + print >> toolsFile, ' '.join(guidedSectionTool) + toolsFile.close() + + ## Returns the full path of the tool. + # + def GetFullPathOfTool (self, tool): + if os.path.exists(tool): + return os.path.realpath(tool) + else: + # We need to search for the tool using the + # PATH environment variable. + for dirInPath in os.environ['PATH'].split(os.pathsep): + foundPath = os.path.join(dirInPath, tool) + if os.path.exists(foundPath): + return os.path.realpath(foundPath) + + # If the tool was not found in the path then we just return + # the input tool. + return tool + + ## Launch the module or platform build + # + def Launch(self): + if self.ModuleFile == None or self.ModuleFile == "": + if not self.SpawnMode or self.Target not in ["", "all"]: + self.SpawnMode = False + self._BuildPlatform() + else: + self._MultiThreadBuildPlatform() + self.CreateGuidedSectionToolsFile() + else: + self.SpawnMode = False + self._BuildModule() + + ## Do some clean-up works when error occurred + def Relinquish(self): + OldLogLevel = EdkLogger.GetLevel() + EdkLogger.SetLevel(EdkLogger.ERROR) + #self.DumpBuildData() + Utils.Progressor.Abort() + if self.SpawnMode == True: + BuildTask.Abort() + EdkLogger.SetLevel(OldLogLevel) + + def DumpBuildData(self): + CacheDirectory = os.path.join(self.WorkspaceDir, gBuildCacheDir) + Utils.CreateDirectory(CacheDirectory) + Utils.DataDump(Utils.gFileTimeStampCache, os.path.join(CacheDirectory, "gFileTimeStampCache")) + Utils.DataDump(Utils.gDependencyDatabase, os.path.join(CacheDirectory, "gDependencyDatabase")) + + def RestoreBuildData(self): + FilePath = os.path.join(self.WorkspaceDir, gBuildCacheDir, "gFileTimeStampCache") + if Utils.gFileTimeStampCache == {} and os.path.isfile(FilePath): + Utils.gFileTimeStampCache = Utils.DataRestore(FilePath) + if Utils.gFileTimeStampCache == None: + Utils.gFileTimeStampCache = {} + + FilePath = os.path.join(self.WorkspaceDir, gBuildCacheDir, "gDependencyDatabase") + if Utils.gDependencyDatabase == {} and os.path.isfile(FilePath): + Utils.gDependencyDatabase = Utils.DataRestore(FilePath) + if Utils.gDependencyDatabase == None: + Utils.gDependencyDatabase = {} + +def ParseDefines(DefineList=[]): + DefineDict = {} + if DefineList != None: + for Define in DefineList: + DefineTokenList = Define.split("=", 1) + if len(DefineTokenList) == 1: + DefineDict[DefineTokenList[0]] = "" + else: + DefineDict[DefineTokenList[0]] = DefineTokenList[1].strip() + return DefineDict + +gParamCheck = [] +def SingleCheckCallback(option, opt_str, value, parser): + if option not in gParamCheck: + setattr(parser.values, option.dest, value) + gParamCheck.append(option) + else: + parser.error("Option %s only allows one instance in command line!" % option) + +## 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(): + Parser = OptionParser(description=__copyright__,version=__version__,prog="build.exe",usage="%prog [options] [all|fds|genc|genmake|clean|cleanall|cleanlib|modules|libraries|run]") + Parser.add_option("-a", "--arch", action="append", type="choice", choices=['IA32','X64','IPF','EBC','ARM'], dest="TargetArch", + help="ARCHS is one of list: IA32, X64, IPF, ARM or EBC, which overrides target.txt's TARGET_ARCH definition. To specify more archs, please repeat this option.") + Parser.add_option("-p", "--platform", action="callback", type="string", dest="PlatformFile", callback=SingleCheckCallback, + help="Build the platform specified by the DSC file name argument, overriding target.txt's ACTIVE_PLATFORM definition.") + Parser.add_option("-m", "--module", action="callback", type="string", dest="ModuleFile", callback=SingleCheckCallback, + help="Build the module specified by the INF file name argument.") + Parser.add_option("-b", "--buildtarget", action="append", type="choice", choices=['DEBUG','RELEASE'], dest="BuildTarget", + help="BuildTarget is one of list: DEBUG, RELEASE, which overrides target.txt's TARGET definition. To specify more TARGET, please repeat this option.") + Parser.add_option("-t", "--tagname", action="append", type="string", dest="ToolChain", + help="Using the Tool Chain Tagname to build the platform, overriding target.txt's TOOL_CHAIN_TAG definition.") + Parser.add_option("-x", "--sku-id", action="callback", type="string", dest="SkuId", callback=SingleCheckCallback, + help="Using this name of SKU ID to build the platform, overriding SKUID_IDENTIFIER in DSC file.") + + Parser.add_option("-n", action="callback", type="int", dest="ThreadNumber", callback=SingleCheckCallback, + help="Build the platform using multi-threaded compiler. The value overrides target.txt's MAX_CONCURRENT_THREAD_NUMBER. Less than 2 will disable multi-thread builds.") + + Parser.add_option("-f", "--fdf", action="callback", type="string", dest="FdfFile", callback=SingleCheckCallback, + help="The name of the FDF file to use, which overrides the setting in the DSC file.") + Parser.add_option("-r", "--rom-image", action="append", type="string", dest="RomImage", default=[], + help="The name of FD to be generated. The name must be from [FD] section in FDF file.") + Parser.add_option("-i", "--fv-image", action="append", type="string", dest="FvImage", default=[], + help="The name of FV to be generated. The name must be from [FV] section in FDF file.") + + Parser.add_option("-u", "--skip-autogen", action="store_true", dest="SkipAutoGen", help="Skip AutoGen step.") + Parser.add_option("-e", "--re-parse", action="store_true", dest="Reparse", help="Re-parse all meta-data files.") + + Parser.add_option("-c", "--case-insensitive", action="store_true", dest="CaseInsensitive", help="Don't check case of file name.") + + # Parser.add_option("-D", "--define", action="append", dest="Defines", metavar="NAME[=[VALUE]]", + # help="Define global macro which can be used in DSC/DEC/INF files.") + + Parser.add_option("-w", "--warning-as-error", action="store_true", dest="WarningAsError", help="Treat warning in tools as error.") + Parser.add_option("-j", "--log", action="store", dest="LogFile", help="Put log in specified file as well as on console.") + + Parser.add_option("-s", "--silent", action="store_true", type=None, dest="SilentMode", + help="Make use of silent mode of (n)make.") + Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.") + Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed, "\ + "including library instances selected, final dependency expression, "\ + "and warning messages, etc.") + Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.") + + (Opt, Args)=Parser.parse_args() + return (Opt, Args) + +## 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(): + StartTime = time.time() + + # Initialize log system + EdkLogger.Initialize() + + # + # Parse the options and args + # + (Option, Target) = MyOptionParser() + GlobalData.gOptions = Option + GlobalData.gCaseInsensitive = Option.CaseInsensitive + + # Set log level + if Option.verbose != None: + EdkLogger.SetLevel(EdkLogger.VERBOSE) + elif Option.quiet != None: + EdkLogger.SetLevel(EdkLogger.QUIET) + elif Option.debug != None: + EdkLogger.SetLevel(Option.debug + 1) + else: + EdkLogger.SetLevel(EdkLogger.INFO) + + if Option.LogFile != None: + EdkLogger.SetLogFile(Option.LogFile) + + if Option.WarningAsError == True: + EdkLogger.SetWarningAsError() + + if platform.platform().find("Windows") >= 0: + GlobalData.gIsWindows = True + else: + GlobalData.gIsWindows = False + + EdkLogger.quiet(time.strftime("%H:%M:%S, %b.%d %Y ", time.localtime()) + "[%s]\n" % platform.platform()) + ReturnCode = 0 + MyBuild = None + try: + if len(Target) == 0: + Target = "all" + elif len(Target) >= 2: + EdkLogger.error("build", OPTION_NOT_SUPPORTED, "More than one targets are not supported.", + ExtraData="Please select one of: %s" %(' '.join(gSupportedTarget))) + else: + Target = Target[0].lower() + + if Target not in gSupportedTarget: + EdkLogger.error("build", OPTION_NOT_SUPPORTED, "Not supported target [%s]." % Target, + ExtraData="Please select one of: %s" %(' '.join(gSupportedTarget))) + + # GlobalData.gGlobalDefines = ParseDefines(Option.Defines) + # + # Check environment variable: EDK_TOOLS_PATH, WORKSPACE, PATH + # + CheckEnvVariable() + Workspace = os.getenv("WORKSPACE") + # + # Get files real name in workspace dir + # + GlobalData.gAllFiles = Utils.DirCache(Workspace) + + WorkingDirectory = os.getcwd() + if not Option.ModuleFile: + FileList = glob.glob(os.path.normpath(os.path.join(WorkingDirectory, '*.inf'))) + FileNum = len(FileList) + if FileNum >= 2: + EdkLogger.error("build", OPTION_NOT_SUPPORTED, "There are %d INF files in %s." % (FileNum, WorkingDirectory), + ExtraData="Please use '-m ' switch to choose one.") + elif FileNum == 1: + Option.ModuleFile = NormFile(FileList[0], Workspace) + + if Option.ModuleFile: + Option.ModuleFile = PathClass(Option.ModuleFile, Workspace) + ErrorCode, ErrorInfo = Option.ModuleFile.Validate(".inf", False) + if ErrorCode != 0: + EdkLogger.error("build", ErrorCode, ExtraData=ErrorInfo) + + if Option.PlatformFile != None: + Option.PlatformFile = PathClass(Option.PlatformFile, Workspace) + ErrorCode, ErrorInfo = Option.PlatformFile.Validate(".dsc", False) + if ErrorCode != 0: + EdkLogger.error("build", ErrorCode, ExtraData=ErrorInfo) + + if Option.FdfFile != None: + Option.FdfFile = PathClass(Option.FdfFile, Workspace) + ErrorCode, ErrorInfo = Option.FdfFile.Validate(".fdf", False) + if ErrorCode != 0: + EdkLogger.error("build", ErrorCode, ExtraData=ErrorInfo) + + MyBuild = Build(Target, Workspace, Option.PlatformFile, Option.ModuleFile, + Option.TargetArch, Option.ToolChain, Option.BuildTarget, + Option.FdfFile, Option.RomImage, Option.FvImage, + None, Option.SilentMode, Option.ThreadNumber, + Option.SkipAutoGen, Option.Reparse, Option.SkuId) + MyBuild.Launch() + #MyBuild.DumpBuildData() + except FatalError, X: + if MyBuild != None: + # for multi-thread build exits safely + MyBuild.Relinquish() + if Option != None and Option.debug != None: + EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc()) + ReturnCode = X.args[0] + except Warning, X: + # error from Fdf parser + if MyBuild != None: + # for multi-thread build exits safely + MyBuild.Relinquish() + if Option != None and Option.debug != None: + EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc()) + else: + EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError = False) + ReturnCode = FORMAT_INVALID + except KeyboardInterrupt: + ReturnCode = ABORT_ERROR + if Option != None and Option.debug != None: + EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc()) + except: + if MyBuild != None: + # for multi-thread build exits safely + MyBuild.Relinquish() + + # try to get the meta-file from the object causing exception + Tb = sys.exc_info()[-1] + MetaFile = GlobalData.gProcessingFile + while Tb != None: + if 'self' in Tb.tb_frame.f_locals and hasattr(Tb.tb_frame.f_locals['self'], 'MetaFile'): + MetaFile = Tb.tb_frame.f_locals['self'].MetaFile + Tb = Tb.tb_next + EdkLogger.error( + "\nbuild", + CODE_ERROR, + "Unknown fatal error when processing [%s]" % MetaFile, + ExtraData="\n(Please send email to dev@buildtools.tianocore.org 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: + Utils.Progressor.Abort() + + if MyBuild != None: + MyBuild.Db.Close() + + if ReturnCode == 0: + Conclusion = "Done" + elif ReturnCode == ABORT_ERROR: + Conclusion = "Aborted" + else: + Conclusion = "Failed" + FinishTime = time.time() + BuildDuration = time.strftime("%M:%S", time.gmtime(int(round(FinishTime - StartTime)))) + EdkLogger.SetLevel(EdkLogger.QUIET) + EdkLogger.quiet("\n- %s -\n%s [%s]" % (Conclusion, time.strftime("%H:%M:%S, %b.%d %Y", time.localtime()), BuildDuration)) + + return ReturnCode + +if __name__ == '__main__': + r = Main() + ## 0-127 is a safe return range, and 1 is a standard default error + if r < 0 or r > 127: r = 1 + sys.exit(r) + diff --git a/BaseTools/Source/Python/fpd2dsc/EdkIIWorkspaceGuidsInfo.py b/BaseTools/Source/Python/fpd2dsc/EdkIIWorkspaceGuidsInfo.py new file mode 100644 index 0000000000..528dbf3ddb --- /dev/null +++ b/BaseTools/Source/Python/fpd2dsc/EdkIIWorkspaceGuidsInfo.py @@ -0,0 +1,327 @@ +## @file +# Collects the Guid Information in current workspace. +# +# Copyright (c) 2007, 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 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 fnmatch +from Common.EdkIIWorkspace import EdkIIWorkspace +from Common.MigrationUtilities import * + +## A class for EdkII work space to resolve Guids +# +# This class inherits from EdkIIWorkspace and collects the Guids information +# in current workspace. The Guids information is important to translate the +# package Guids and recommended library instances Guids to relative file path +# (to workspace directory) in MSA files. +# +class EdkIIWorkspaceGuidsInfo(EdkIIWorkspace): + + ## The classconstructor + # + # The constructor initialize workspace directory. It does not collect + # pakage and module Guids info at initialization; instead, it collects them + # on the fly. + # + # @param self The object pointer + # + def __init__(self): + # Initialize parent class. + EdkIIWorkspace.__init__(self) + # The internal map from Guid to FilePath. + self.__GuidToFilePath = {} + # The internal package directory list. + self.__PackageDirList = [] + # The internal flag to indicate whether package Guids info has been initialized + # to avoid re-collection collected. + self.__PackageGuidInitialized = False + # The internal flag to indicate whether module Guids info has been initialized + # to avoid re-collection collected. + self.__ModuleGuidInitialized = False + + ## Add Guid, Version and FilePath to Guids database + # + # Add Guid, Version and FilePath to Guids database. It constructs a map + # table from Guid, Version to FilePath internally. If also detects possible + # Guid collision. For now, the version information is simply ignored and + # Guid value itself acts as master key. + # + # @param self The object pointer + # @param Guid The Guid Value + # @param Version The version information + # @param FilePath The Guid related file path + # + # @retval True The Guid value is successfully added to map table + # @retval False The Guid is an empty string or the map table + # already contains a same Guid + # + def __AddGuidToFilePath(self, Guid, Version, FilePath): + if Guid == "": + EdkLogger.info("Cannot find Guid in file %s" % FilePath) + return False + #Add the Guid value to map table to ensure case insensitive comparison. + OldFilePath = self.__GuidToFilePath.setdefault(Guid.lower(), FilePath) + if OldFilePath == FilePath: + EdkLogger.verbose("File %s has new Guid '%s'" % (FilePath, Guid)) + return True + else: + EdkLogger.info("File %s has duplicate Guid with & %s" % (FilePath, OldFilePath)) + return False + + + ## Gets file information from a module description file + # + # Extracts Module Name, File Guid and Version number from INF, MSA and NMSA + # file. It supports to exact such information from text based INF file or + # XML based (N)MSA file. + # + # @param self The object pointer + # @param FileName The input module file name + # + # @retval True This module file represents a new module discovered + # in current workspace + # @retval False This module file is not regarded as a valid module + # The File Guid cannot be extracted or the another + # file with the same Guid already exists + # + def __GetModuleFileInfo(self, FileName): + if fnmatch.fnmatch(FileName, "*.inf"): + TagTuple = ("BASE_NAME", "FILE_GUID", "VERSION_STRING") + (Name, Guid, Version) = GetTextFileInfo(FileName, TagTuple) + else : + XmlTag1 = "ModuleSurfaceArea/MsaHeader/ModuleName" + XmlTag2 = "ModuleSurfaceArea/MsaHeader/GuidValue" + XmlTag3 = "ModuleSurfaceArea/MsaHeader/Version" + TagTuple = (XmlTag1, XmlTag2, XmlTag3) + (Name, Guid, Version) = GetXmlFileInfo(FileName, TagTuple) + + return self.__AddGuidToFilePath(Guid, Version, FileName) + + + ## Gets file information from a package description file + # + # Extracts Package Name, File Guid and Version number from INF, SPD and NSPD + # file. It supports to exact such information from text based DEC file or + # XML based (N)SPD file. EDK Compatibility Package is hardcoded to be + # ignored since no EDKII INF file depends on that package. + # + # @param self The object pointer + # @param FileName The input package file name + # + # @retval True This package file represents a new package + # discovered in current workspace + # @retval False This package is not regarded as a valid package + # The File Guid cannot be extracted or the another + # file with the same Guid already exists + # + def __GetPackageFileInfo(self, FileName): + if fnmatch.fnmatch(FileName, "*.dec"): + TagTuple = ("PACKAGE_NAME", "PACKAGE_GUID", "PACKAGE_VERSION") + (Name, Guid, Version) = GetTextFileInfo(FileName, TagTuple) + else: + XmlTag1 = "PackageSurfaceArea/SpdHeader/PackageName" + XmlTag2 = "PackageSurfaceArea/SpdHeader/GuidValue" + XmlTag3 = "PackageSurfaceArea/SpdHeader/Version" + TagTuple = (XmlTag1, XmlTag2, XmlTag3) + (Name, Guid, Version) = GetXmlFileInfo(FileName, TagTuple) + + if Name == "EdkCompatibilityPkg": + # Do not scan EDK compatibitilty package to avoid Guid collision + # with those in EDK Glue Library. + EdkLogger.verbose("Bypass EDK Compatibility Pkg") + return False + + return self.__AddGuidToFilePath(Guid, Version, FileName) + + ## Iterate on all package files listed in framework database file + # + # Yields all package description files listed in framework database files. + # The framework database file describes the packages current workspace + # includes. + # + # @param self The object pointer + # + def __FrameworkDatabasePackageFiles(self): + XmlFrameworkDb = XmlParseFile(self.WorkspaceFile) + XmlTag = "FrameworkDatabase/PackageList/Filename" + for PackageFile in XmlElementList(XmlFrameworkDb, XmlTag): + yield os.path.join(self.WorkspaceDir, PackageFile) + + + ## Iterate on all package files in current workspace directory + # + # Yields all package description files listed in current workspace + # directory. This happens when no framework database file exists. + # + # @param self The object pointer + # + def __TraverseAllPackageFiles(self): + for Path, Dirs, Files in os.walk(self.WorkspaceDir): + # Ignore svn version control directory. + if ".svn" in Dirs: + Dirs.remove(".svn") + if "Build" in Dirs: + Dirs.remove("Build") + # Assume priority from high to low: DEC, NSPD, SPD. + PackageFiles = fnmatch.filter(Files, "*.dec") + if len(PackageFiles) == 0: + PackageFiles = fnmatch.filter(Files, "*.nspd") + if len(PackageFiles) == 0: + PackageFiles = fnmatch.filter(Files, "*.spd") + + for File in PackageFiles: + # Assume no more package decription file in sub-directory. + del Dirs[:] + yield os.path.join(Path, File) + + ## Iterate on all module files in current package directory + # + # Yields all module description files listed in current package + # directory. + # + # @param self The object pointer + # + def __TraverseAllModuleFiles(self): + for PackageDir in self.__PackageDirList: + for Path, Dirs, Files in os.walk(PackageDir): + # Ignore svn version control directory. + if ".svn" in Dirs: + Dirs.remove(".svn") + # Assume priority from high to low: INF, NMSA, MSA. + ModuleFiles = fnmatch.filter(Files, "*.inf") + if len(ModuleFiles) == 0: + ModuleFiles = fnmatch.filter(Files, "*.nmsa") + if len(ModuleFiles) == 0: + ModuleFiles = fnmatch.filter(Files, "*.msa") + + for File in ModuleFiles: + yield os.path.join(Path, File) + + ## Initialize package Guids info mapping table + # + # Collects all package guids map to package decription file path. This + # function is invokes on demand to avoid unnecessary directory scan. + # + # @param self The object pointer + # + def __InitializePackageGuidInfo(self): + if self.__PackageGuidInitialized: + return + + EdkLogger.verbose("Start to collect Package Guids Info.") + + WorkspaceFile = os.path.join("Conf", "FrameworkDatabase.db") + self.WorkspaceFile = os.path.join(self.WorkspaceDir, WorkspaceFile) + + # Try to find the frameworkdatabase file to discover package lists + if os.path.exists(self.WorkspaceFile): + TraversePackage = self.__FrameworkDatabasePackageFiles + EdkLogger.verbose("Package list bases on: %s" % self.WorkspaceFile) + else: + TraversePackage = self.__TraverseAllPackageFiles + EdkLogger.verbose("Package list in: %s" % self.WorkspaceDir) + + for FileName in TraversePackage(): + if self.__GetPackageFileInfo(FileName): + PackageDir = os.path.dirname(FileName) + EdkLogger.verbose("Find new package directory %s" % PackageDir) + self.__PackageDirList.append(PackageDir) + + self.__PackageGuidInitialized = True + + ## Initialize module Guids info mapping table + # + # Collects all module guids map to module decription file path. This + # function is invokes on demand to avoid unnecessary directory scan. + # + # @param self The object pointer + # + def __InitializeModuleGuidInfo(self): + if self.__ModuleGuidInitialized: + return + EdkLogger.verbose("Start to collect Module Guids Info") + + self.__InitializePackageGuidInfo() + for FileName in self.__TraverseAllModuleFiles(): + if self.__GetModuleFileInfo(FileName): + EdkLogger.verbose("Find new module %s" % FileName) + + self.__ModuleGuidInitialized = True + + ## Get Package file path by Package Guid and Version + # + # Translates the Package Guid and Version to a file path relative + # to workspace directory. If no package in current workspace match the + # input Guid, an empty file path is returned. For now, the version + # value is simply ignored. + # + # @param self The object pointer + # @param Guid The Package Guid value to look for + # @param Version The Package Version value to look for + # + def ResolvePackageFilePath(self, Guid, Version = ""): + self.__InitializePackageGuidInfo() + + EdkLogger.verbose("Resolve Package Guid '%s'" % Guid) + FileName = self.__GuidToFilePath.get(Guid.lower(), "") + if FileName == "": + EdkLogger.info("Cannot resolve Package Guid '%s'" % Guid) + else: + FileName = self.WorkspaceRelativePath(FileName) + FileName = os.path.splitext(FileName)[0] + ".dec" + FileName = FileName.replace("\\", "/") + return FileName + + ## Get Module file path by Module Guid and Version + # + # Translates the Module Guid and Version to a file path relative + # to workspace directory. If no module in current workspace match the + # input Guid, an empty file path is returned. For now, the version + # value is simply ignored. + # + # @param self The object pointer + # @param Guid The Module Guid value to look for + # @param Version The Module Version value to look for + # + def ResolveModuleFilePath(self, Guid, Version = ""): + self.__InitializeModuleGuidInfo() + + EdkLogger.verbose("Resolve Module Guid '%s'" % Guid) + FileName = self.__GuidToFilePath.get(Guid.lower(), "") + if FileName == "": + EdkLogger.info("Cannot resolve Module Guid '%s'" % Guid) + else: + FileName = self.WorkspaceRelativePath(FileName) + FileName = os.path.splitext(FileName)[0] + ".inf" + FileName = FileName.replace("\\", "/") + return FileName + +# A global class object of EdkIIWorkspaceGuidsInfo for external reference. +gEdkIIWorkspaceGuidsInfo = EdkIIWorkspaceGuidsInfo() + +# This acts like the main() function for the script, unless it is 'import'ed +# into another script. +if __name__ == '__main__': + # Test the translation of package Guid. +# MdePkgGuid = "1E73767F-8F52-4603-AEB4-F29B510B6766" +# OldMdePkgGuid = "5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec" +# print gEdkIIWorkspaceGuidsInfo.ResolveModuleFilePath(MdePkgGuid) +# print gEdkIIWorkspaceGuidsInfo.ResolveModuleFilePath(OldMdePkgGuid) + + # Test the translation of module Guid. +# UefiLibGuid = "3a004ba5-efe0-4a61-9f1a-267a46ae5ba9" +# UefiDriverModelLibGuid = "52af22ae-9901-4484-8cdc-622dd5838b09" +# print gEdkIIWorkspaceGuidsInfo.ResolvePlatformFilePath(UefiLibGuid) +# print gEdkIIWorkspaceGuidsInfo.ResolvePlatformFilePath(UefiDriverModelLibGuid) + pass \ No newline at end of file diff --git a/BaseTools/Source/Python/fpd2dsc/LoadFpd.py b/BaseTools/Source/Python/fpd2dsc/LoadFpd.py new file mode 100644 index 0000000000..cc97ec5521 --- /dev/null +++ b/BaseTools/Source/Python/fpd2dsc/LoadFpd.py @@ -0,0 +1,1039 @@ +## @file +# Open an FPD file and load all its contents to a PlatformClass object. +# +# Copyright (c) 2007, 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 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 +from CommonDataClass.PlatformClass import * +from CommonDataClass.FdfClass import * +from Common.XmlRoutines import * +from Common.MigrationUtilities import * +from EdkIIWorkspaceGuidsInfo import gEdkIIWorkspaceGuidsInfo + +## Load Platform Header +# +# Read an input Platform XML DOM object and return Platform Header class object +# contained in the DOM object. +# +# @param XmlFpd An XML DOM object read from FPD file +# @param FpdFileName The file path of FPD File +# +# @retvel PlatformHeader A new Platform Header object loaded from XmlFpd +# +def LoadPlatformHeader(XmlFpd, FpdFileName): + PlatformHeader = PlatformHeaderClass() + + XmlTag = "PlatformSurfaceArea/PlatformHeader" + FpdHeader = XmlNode(XmlFpd, XmlTag) + + SetIdentification(PlatformHeader, FpdHeader, "PlatformName", FpdFileName) + SetCommonHeader(PlatformHeader, FpdHeader) + + XmlTag = "PlatformSurfaceArea/PlatformHeader/Specification" + List = XmlElement(XmlFpd, XmlTag).split() + SpecificationName = List[0] + SpecificationValue = List[1] + PlatformHeader.Specification = {SpecificationName:SpecificationValue} + + XmlTag = "PlatformSurfaceArea/PlatformDefinitions/SupportedArchitectures" + PlatformHeader.SupArchList = XmlElement(XmlFpd, XmlTag).split() + + XmlTag = "PlatformSurfaceArea/PlatformDefinitions/BuildTargets" + PlatformHeader.BuildTargets = XmlElement(XmlFpd, XmlTag).split() + + XmlTag = "PlatformSurfaceArea/PlatformDefinitions/IntermediateDirectories" + PlatformHeader.IntermediateDirectories = XmlElement(XmlFpd, XmlTag) + + XmlTag = "PlatformSurfaceArea/PlatformDefinitions/OutputDirectory" + PlatformHeader.OutputDirectory = XmlElement(XmlFpd, XmlTag) + + XmlTag = "PlatformSurfaceArea/PlatformDefinitions/SkuInfo" + List = map(LoadSkuId, XmlList(XmlFpd, XmlTag)) + if List != []: + PlatformHeader.SkuIdName = List[0] + + return PlatformHeader + +## Load a Platform SkuId +# +# Read an input Platform XML DOM object and return a list of Platform SkuId +# contained in the DOM object. +# +# @param XmlPlatformSkuInfo An XML DOM object read from FPD file +# +# @retvel PlatformSkuInfo A SkuInfo loaded from XmlFpd +# +def LoadPlatformSkuInfo(XmlPlatformSkuInfo): + XmlTag = "SkuInfo/SkuId" + SkuInfo = [] + SkuId = XmlElement(XmlPlatformSkuInfo, XmlTag) + SkuInfo.append(SkuId) + + XmlTag = "SkuInfo/Value" + Value = XmlElement(XmlPlatformSkuInfo, XmlTag) + SkuInfo.append(Value) + return SkuInfo + +## Load a Platform SkuId +# +# Read an input Platform XML DOM object and return a list of Platform SkuId +# contained in the DOM object. +# +# @param XmlSkuInfo An XML DOM object read from FPD file +# +# @retvel List A list of SkuId and SkuValue loaded from XmlFpd +# +def LoadSkuId(XmlSkuInfo): + XmlTag = "SkuInfo/UiSkuName" + SkuValue = XmlElement(XmlSkuInfo, XmlTag) + + XmlTag = "SkuInfo/UiSkuName" + List = map(LoadSkuID, XmlList(XmlSkuInfo, XmlTag)) + if List != []: + SkuID = List[0] + #SkuID = XmlAttribute(XmlSkuInfo, XmlTag) + List = [] + List.append(SkuID) + List.append(SkuValue) + return List + +def LoadSkuID(XmlUiSkuName): + XmlTag = "SkuID" + SkuID = XmlAttribute(XmlUiSkuName, XmlTag) + return SkuID + +## Load a list of Platform SkuIds +# +# Read an input Platform XML DOM object and return a list of Platform SkuId +# contained in the DOM object. +# +# @param XmlFpd An XML DOM object read from FPD file +# +# @retvel PlatformSkuIds A platform SkuIds object loaded from XmlFpd +# +def LoadPlatformSkuInfos(XmlFpd): + PlatformSkuIds = SkuInfoListClass() + + SkuInfoList = [] + + XmlTag = "PlatformSurfaceArea/PlatformDefinitions/SkuInfo" + List = map(LoadSkuId, XmlList(XmlFpd, XmlTag)) + SkuInfoList = List + + XmlTag = "PlatformSurfaceArea/PlatformDefinitions/SkuInfo/UiSkuName" + Value = XmlElement(XmlFpd, XmlTag) + + XmlTag = "PlatformSurfaceArea/DynamicPcdBuildDefinitions/PcdBuildData/SkuInfo" + # here return a List + List = map(LoadPlatformSkuInfo, XmlList(XmlFpd, XmlTag)) + + for SkuInfo in List: + SkuId = SkuInfo[0] + Value = SkuInfo[1] + + SkuInfoList.append(SkuInfo) + + PlatformSkuIds.SkuInfoList = SkuInfoList + + return PlatformSkuIds + +## Load Platform Module Build Option +# +# Read an input Platform XML DOM object and return Platform Module Build Option class object +# contained in the DOM object. +# +# @param XmlModuleBuildOption An XML DOM object read from FPD file +# +# @retvel PlatformBuildOption A Platform Build Option object loaded from XmlFpd +# +def LoadModuleBuildOption(XmlModuleBuildOption): + PlatformBuildOption = PlatformBuildOptionClass() + PlatformBuildOption.UserDefinedAntTasks = {} + + XmlTag = "BuildOptions/Options/Option" + PlatformBuildOption.Options = map(LoadBuildOption, XmlList(XmlModuleBuildOption, XmlTag)) + + PlatformBuildOption.UserExtensions = {} + PlatformBuildOption.FfsKeyList = {} + return PlatformBuildOption + +## Load Platform Module Extern +# +# Read an input Platform XML DOM object and return Platform Module Extern class object +# contained in the DOM object. +# +# @param XmlModuleExtern An XML DOM object read from FPD file +# +# @retvel PlatformModuleExtern A Platform Module Extern object loaded from XmlFpd +# +def LoadModuleExtern(XmlModuleExtern): + PlatformModuleExtern = [] + + XmlTag = "Externs/PcdIsDriver" + PcdIsDriver = XmlElement(XmlModuleExtern, XmlTag) + PlatformModuleExtern.append(PcdIsDriver) + + XmlTag = "Externs/Specification" + Specification = XmlElement(XmlModuleExtern, XmlTag) + PlatformModuleExtern.append(Specification) + + XmlTag = "Externs/Extern" + + return PlatformModuleExtern + +## Load Platform ModuleSaBuildOptions +# +# Read an input Platform XML DOM object and return Platform ModuleSaBuildOptions class object +# contained in the DOM object. +# +# @param XmlModuleSaBuildOptions An XML DOM object read from FPD file +# +# @retvel PlatformBuildOptions A list of Platform ModuleSaBuildOption object loaded from XmlFpd +# +def LoadPlatformModuleSaBuildOption(XmlModuleSA): + PlatformModuleSaBuildOption = PlatformBuildOptionClasses() + + XmlTag = "ModuleSA/ModuleSaBuildOptions/FvBinding" + PlatformModuleSaBuildOption.FvBinding = XmlElement(XmlModuleSA, XmlTag) + + XmlTag = "ModuleSA/ModuleSaBuildOptions/FfsFormatKey" + PlatformModuleSaBuildOption.FfsFormatKey = XmlElement(XmlModuleSA, XmlTag) + + XmlTag = "ModuleSA/ModuleSaBuildOptions/FfsFileNameGuid" + PlatformModuleSaBuildOption.FfsFileNameGuid = XmlElement(XmlModuleSA, XmlTag) + + XmlTag = "ModuleSA/ModuleSaBuildOptions/Options/Option" + PlatformModuleSaBuildOption.BuildOptionList = map(LoadBuildOption, XmlList(XmlModuleSA, XmlTag)) + + return PlatformModuleSaBuildOption + +## Load a list of Platform Library Classes +# +# Read an input Platform XML DOM object and return a list of Library Classes +# contained in the DOM object. +# +# @param XmlLibraryInstance An XML DOM object read from FPD file +# +# @retvel LibraryInstance A Library Instance loaded from XmlFpd +# +def LoadPlatformModuleLibraryInstance(XmlLibraryInstance): + LibraryInstance = [] + + XmlTag = "ModuleGuid" + ModuleGuid = XmlAttribute(XmlLibraryInstance, XmlTag) + + ModulePath = gEdkIIWorkspaceGuidsInfo.ResolveModuleFilePath(ModuleGuid) + ModuleMSAFile = ModulePath.replace('.inf', '.msa') + WorkSpace = os.getenv('WORKSPACE') + ModuleMSAFileName = os.path.join(WorkSpace, ModuleMSAFile) + XmlMsa = XmlParseFile(ModuleMSAFileName) + + XmlTag = "ModuleSurfaceArea/LibraryClassDefinitions/LibraryClass/Keyword" + Name = XmlElement(XmlMsa, XmlTag) + LibraryInstance.append(Name) + LibraryInstance.append(ModulePath) + + #XmlTag = "PackageGuid" + #PackageGuid = XmlAttribute(XmlLibraryInstance, XmlTag) + #LibraryInstance.append(PackageGuid) + return LibraryInstance + +## Load a Library Class +# +# Read an input Platform XML DOM object and return a library class object +# contained in the DOM object. +# +# @param XmlLibraryClass An XML DOM object read from FPD file +# +# @retvel SupModuleList A Library Class Supported Module List object loaded from XmlFpd +# +def LoadLibraryClassSupModuleList(XmlLibraryClass): + XmlTag = "Usage" + Usage = XmlAttribute(XmlLibraryClass, XmlTag) + if Usage == "ALWAYS_PRODUCED": + XmlTag = "SupModuleList" + SupModuleList = XmlAttribute(XmlLibraryClass, XmlTag).split() + return SupModuleList + +## Load Platform Library Class +# +# Read an input Platform XML DOM object and return Platform module class object +# contained in the DOM object. +# +# @param XmlLibraries An XML DOM object read from FPD file +# +# @retvel PlatformLibraryClass A Platform Library Class object loaded from XmlFpd +# +def LoadPlatformLibraryClass(XmlPlatformLibraryClass): + PlatformLibraryInstance = PlatformLibraryClass() + + XmlTag = "ModuleGuid" + LibraryInstanceModuleGuid = XmlAttribute(XmlPlatformLibraryClass, XmlTag) + + XmlTag = "PackageGuid" + LibraryInstancePackageGuid = XmlAttribute(XmlPlatformLibraryClass, XmlTag) + + LibraryInstancePath = gEdkIIWorkspaceGuidsInfo.ResolveModuleFilePath(LibraryInstanceModuleGuid) + + if LibraryInstancePath != "": # if LibraryInstancePath == "" that's because the module guid cannot be resolved + PlatformLibraryInstance.FilePath = LibraryInstancePath + # replace *.inf to *.msa + LibraryInstanceMSAName = LibraryInstancePath.replace('.inf', '.msa') + WorkSpace = os.getenv('WORKSPACE') + LibraryInstanceMSAPath = os.path.join(WorkSpace, LibraryInstanceMSAName) + + PlatformLibraryInstance.FilePath = LibraryInstancePath + + XmlMsa = XmlParseFile(LibraryInstanceMSAPath) + + XmlTag = "ModuleSurfaceArea/MsaHeader/ModuleName" + PlatformLibraryInstance.Name = XmlElement(XmlMsa, XmlTag) + + XmlTag = "ModuleSurfaceArea/MsaHeader/ModuleType" + PlatformLibraryInstance.ModuleType = XmlElement(XmlMsa, XmlTag) + + if PlatformLibraryInstance.ModuleType != "BASE": + XmlTag = "ModuleSurfaceArea/LibraryClassDefinitions/LibraryClass" + List = map(LoadLibraryClassSupModuleList, XmlList(XmlMsa, XmlTag)) + if List != []: + PlatformLibraryInstance.SupModuleList = List[0] + XmlTag = "ModuleSurfaceArea/ModuleDefinitions/SupportedArchitectures" + PlatformLibraryInstance.SupArchList = XmlElement(XmlMsa, XmlTag).split() + + PlatformLibraryInstance.ModuleGuid = LibraryInstanceModuleGuid + + XmlTag = "ModuleSurfaceArea/MsaHeader/Version" + PlatformLibraryInstance.ModuleVersion = XmlElement(XmlMsa, XmlTag) + + PlatformLibraryInstance.PackageGuid = LibraryInstancePackageGuid + PlatformLibraryInstance.PackageVersion = '' + + return PlatformLibraryInstance + +## Load Platform Library Classes +# +# Read an input Platform XML DOM object and return Platform module class object +# contained in the DOM object. +# +# @param XmlLibraries An XML DOM object read from FPD file +# +# @retvel PlatformLibraryClasses A list of Platform Library Class object loaded from XmlFpd +# +def LoadPlatformLibraryClasses(XmlFpd): + PlatformLibraryInstances = PlatformLibraryClasses() + PlatformLibraryInstances.LibraryList = [] + + List = [] + XmlTag = "PlatformSurfaceArea/FrameworkModules/ModuleSA/Libraries/Instance" + List = map(LoadPlatformLibraryClass, XmlList(XmlFpd, XmlTag)) + #List.sort() + if List == []: + print "Error" + else: + PlatformLibraryInstances.LibraryList = List + + return PlatformLibraryInstances + +## Load Platform module +# +# Read an input Platform XML DOM object and return Platform module class object +# contained in the DOM object. +# +# @param XmlModuleSA An XML DOM object read from FPD file +# +# @retvel PlatformModule A Platform module object loaded from XmlFpd +# +def LoadModuleSA(XmlModuleSA): + PlatformModule = PlatformModuleClass() + + # three parts: Libraries instances, PcdBuildDefinition, ModuleSaBuildOptions + XmlTag = "ModuleSA/Libraries/Instance" + + PlatformModule.LibraryClasses = map(LoadPlatformModuleLibraryInstance, XmlList(XmlModuleSA, XmlTag)) + + XmlTag = "ModuleSA/PcdBuildDefinition/PcdData" + PlatformModule.PcdBuildDefinitions = map(LoadPlatformPcdData, XmlList(XmlModuleSA, XmlTag)) + + XmlTag = "ModuleSA/ModuleSaBuildOptions" + PlatformModule.ModuleSaBuildOption = LoadPlatformModuleSaBuildOption(XmlModuleSA) + + XmlTag = "ModuleSA/BuildOptions" + PlatformModule.BuildOptions = map(LoadModuleBuildOption, XmlList(XmlModuleSA, XmlTag)) #bugbug fix me + + XmlTag = "ModuleSA/Externs" + PlatformModule.Externs = map(LoadModuleExtern, XmlList(XmlModuleSA, XmlTag)) #bugbug fix me + + XmlTag = "SupArchList" + PlatformModule.SupArchList = XmlAttribute(XmlModuleSA, XmlTag).split() + + # the package guid which the module depends on, do not care for now + XmlTag = "PackageGuid" + PlatformModule.PackageGuid = XmlAttribute(XmlModuleSA, XmlTag) + + # the module guid, use this guid to get the module *.msa file and convert it to *.inf file with path + XmlTag = "ModuleGuid" + PlatformModule.ModuleGuid = XmlAttribute(XmlModuleSA, XmlTag) + # use this guid to find the *.msa file path or FilePath $(WORKSPACE)/EdkModulePkg/Core/Dxe/DxeMain.msa + # then convert $(WORKSPACE)/EdkModulePkg/Core/Dxe/DxeMain.msa to $(WORKSPACE)/EdkModulePkg/Core/Dxe/DxeMain.inf, it's FilePath + PlatformModulePath = gEdkIIWorkspaceGuidsInfo.ResolveModuleFilePath(PlatformModule.ModuleGuid) + + PlatformModule.FilePath = PlatformModulePath # *.inf file path + # *.inf back to *.msa + ModuleMSAFileName = PlatformModulePath.replace('.inf', '.msa') + WorkSpace = os.getenv('WORKSPACE') + ModuleMSAFileName = os.path.join(WorkSpace, ModuleMSAFileName) + # Open this module + #ModuleMSA = open(ModuleMSAFileName, "r") + XmlMsa = XmlParseFile(ModuleMSAFileName) + + XmlTag = "ModuleSurfaceArea/MsaHeader/ModuleName" + PlatformModule.Name = XmlElement(XmlMsa, XmlTag) # ModuleName + + XmlTag = "ModuleSurfaceArea/MsaHeader/ModuleType" + PlatformModule.ModuleType = XmlElement(XmlMsa, XmlTag) + + # IA32, X64, IPF and EBC which the module support arch + #XmlTag = "ModuleSurfaceArea/ModuleDefinitions/SupportedArchitectures" + #PlatformModule.SupArchList = XmlElement(XmlMsa, XmlTag).split() + + #XmlTag = "ModuleSurfaceArea/MsaHeader/" + PlatformModule.Type = '' #LIBRARY | LIBRARY_CLASS | MODULE, used by dsc. New in DSC spec + + PlatformModule.ExecFilePath = '' # New in DSC spec + + XmlTag = "ModuleSurfaceArea/MsaHeader/Specification" + PlatformModule.Specifications = XmlElement(XmlMsa, XmlTag).split() + + return PlatformModule + +## Load Platform modules +# +# Read an input Platform XML DOM object and return a list of Platform modules class object +# contained in the DOM object. +# +# @param XmlFpd An XML DOM object read from FPD file +# +# @retvel PlatformModules A list of Platform modules object loaded from XmlFpd +# +def LoadPlatformModules(XmlFpd): + PlatformModules = PlatformModuleClasses() + + XmlTag = "PlatformSurfaceArea/FrameworkModules/ModuleSA" + PlatformModules.ModuleList = map(LoadModuleSA, XmlList(XmlFpd, XmlTag)) + + return PlatformModules + +## Load Platform Flash Definition File +# +# Read an input Platform XML DOM object and return Platform Flash Definition File class object +# contained in the DOM object. +# +# @param XmlFpd An XML DOM object read from FPD file +# @param FpdFileName The file path of FPD File +# +# @retvel PlatformFlashDefinitionFile A new Platform Flash Definition File object loaded from XmlFpd +# +def LoadPlatformFlashDefinitionFile(XmlFpd, FpdFileName): + PlatformFlashDefinitionFile = PlatformFlashDefinitionFileClass() + + XmlTag = "PlatformSurfaceArea/Flash/FlashDefinitionFile" + PlatformFlashDefinitionFile.FilePath = XmlElement(XmlFpd, XmlTag) + + XmlTag = "PlatformSurfaceArea/Flash/FlashDefinitionFile/Id" + PlatformFlashDefinitionFile.Id = XmlAttribute(XmlFpd, XmlTag) + + XmlTag = "PlatformSurfaceArea/Flash/FlashDefinitionFile/UiName" + PlatformFlashDefinitionFile.UiName = XmlAttribute(XmlFpd, XmlTag) + + XmlTag = "PlatformSurfaceArea/Flash/FlashDefinitionFile/Preferred" + PlatformFlashDefinitionFile.Preferred = XmlAttribute(XmlFpd, XmlTag) + + return PlatformFlashDefinitionFile + +## Load Platform User Defined Ant Tasks +# +# Read an input Platform XML DOM object and return platform +# User Defined Ant Tasks contained in the DOM object. +# +# @param XmlUserDefinedAntTasks An XML DOM object read from FPD file +# +# @retvel AntTask An Ant Task loaded from XmlFpd +# +def LoadUserDefinedAntTasks(XmlFpd): + Dict = {} + AntTask = PlatformAntTaskClass() + + XmlTag = "PlatformSurfaceArea/BuildOptions/UserDefinedAntTasks/AntTask/Id" + AntTask.Id = XmlAttribute(XmlFpd, XmlTag) + + XmlTag = "PlatformSurfaceArea/BuildOptions/UserDefinedAntTasks/AntTask/AntCmdOptions" + AntTask.AntCmdOptions = XmlElement(XmlFpd, XmlTag) + + XmlTag = "PlatformSurfaceArea/BuildOptions/UserDefinedAntTasks/AntTask/Filename" + AntTask.FilePath = XmlElement(XmlFpd, XmlTag) + + Dict[AntTask.Id] = AntTask + return Dict + +## Load Platform Build Options +# +# Read an input Platform XML DOM object and return a list of platform +# Build Option contained in the DOM object. +# +# @param XmlBuildOptions An XML DOM object read from FPD file +# +# @retvel PlatformBuildOptions A list of platform Build Options loaded from XmlFpd +# +def LoadBuildOptions(XmlBuildOptions): + XmlTag = "Option" + return map(LoadBuildOption, XmlList(XmlBuildOptions, XmlTag)) # LoadBuildOption is a method in MigrationUtilities.py + +## Load Platform Build Option +# +# Read an input Platform XML DOM object and return a Build Option +# contained in the DOM object. +# +# @param XmlFpd An XML DOM object read from FPD file +# +# @retvel PlatformBuildOption A Build Options loaded from XmlFpd +# +def LoadPlatformBuildOption(XmlBuildOptions): + PlatformBuildOption = PlatformBuildOptionClass() + + # handle UserDefinedAntTasks + XmlTag = "BuildOptions/UserDefinedAntTasks/AntTask" + PlatformBuildOption.UserDefinedAntTasks = LoadUserDefinedAntTasks(XmlTag) + + # handle Options + XmlTag = "BuildOptions/Options/Option" + PlatformBuildOption.Options = map(LoadBuildOption, XmlList(XmlBuildOptions, XmlTag)) + + # handle UserExtensions + XmlTag = "BuildOptions/UserExtensions" + PlatformBuildOption.UserExtensions = LoadUserExtensions(XmlTag) # from MigrationUtilities.py LoadUserExtensions + + # handle Ffs + XmlTag = "BuildOptions/Ffs/FfsKey" + PlatformBuildOption.FfsKeyList = map(LoadPlatformFfs, XmlList(XmlBuildOptions, XmlTag)) + + return PlatformBuildOption + +## Load Platform Ffs Dictionary +# +# Read an input Platform XML DOM object and return a platform Ffs Dictionary +# contained in the DOM object. +# +# @param XmlFpd An XML DOM object read from FPD file +# +# @retvel Dict A platform Ffs Dict loaded from XmlFpd +# +def LoadPlatformFfsDict(XmlFpd): + Dict = {} + XmlTag = "PlatformSurfaceArea/BuildOptions/Ffs" + List = map(LoadPlatformFfs, XmlList(XmlFpd, XmlTag)) + if List != []: + for Ffs in List: + Dict[Ffs.Key] = Ffs + return Dict + +## Load Platform Ffs Section +# +# Read an input Platform XML DOM object and return a platform Ffs Section +# contained in the DOM object. +# +# @param XmlFfs An XML DOM object read from FPD file +# +# @retvel PlatformFfsSection A platform Ffs Section loaded from XmlFpd +# +def LoadPlatformFfsSection(XmlFfsSection): + PlatformFfsSection = PlatformFfsSectionClass() + + XmlTag = "" + PlatformFfsSection.BindingOrder = '' + + XmlTag = "" + PlatformFfsSection.Compressible = '' + + XmlTag = "SectionType" + PlatformFfsSection.SectionType = XmlAttribute(XmlFfsSection, XmlTag) + + XmlTag = "" + PlatformFfsSection.EncapsulationType = '' + + XmlTag = "" + PlatformFfsSection.ToolName = '' + + XmlTag = "" + PlatformFfsSection.Filenames = [] + + XmlTag = "" + PlatformFfsSection.Args = '' + + XmlTag = "" + PlatformFfsSection.OutFile = '' + + XmlTag = "" + PlatformFfsSection.OutputFileExtension = '' + + XmlTag = "" + PlatformFfsSection.ToolNameElement = '' + + return PlatformFfsSection + +## Load Platform Ffs Sections +# +# Read an input Platform XML DOM object and return a platform Ffs Sections +# contained in the DOM object. +# +# @param XmlFfs An XML DOM object read from FPD file +# +# @retvel PlatformFfsSections A platform Ffs Sections loaded from XmlFpd +# +def LoadFfsSections(): + PlatformFfsSections = PlatformFfsSectionsClass() + PlatformFfsSections.BindingOrder = '' + PlatformFfsSections.Compressible = '' + PlatformFfsSections.SectionType = '' + PlatformFfsSections.EncapsulationType = '' + PlatformFfsSections.ToolName = '' + PlatformFfsSections.Section = [] + PlatformFfsSections.Sections = [] + + return PlatformFfsSections + +## Load Platform Ffs Sections +# +# Read an input Platform XML DOM object and return a platform Ffs Sections +# contained in the DOM object. +# +# @param XmlFfs An XML DOM object read from FPD file +# +# @retvel PlatformFfsSections A platform Ffs Sections loaded from XmlFpd +# +def LoadPlatformFfsSections(XmlFfsSections): + PlatformFfsSections = PlatformFfsSectionsClass() + + XmlTag = "" + PlatformFfsSections.BindingOrder = '' + + XmlTag = "" + Compressible = '' + + XmlTag = "" + SectionType = '' + + XmlTag = "EncapsulationType" + EncapsulationType = XmlAttribute(XmlFfsSections, XmlTag) + + XmlTag = "" + ToolName = '' + + XmlTag = "Sections/Section" + Section = [] #[ PlatformFfsSectionClass, ... ] + Section = map(LoadPlatformFfsSection, XmlList(XmlFfsSections, XmlTag)) + + + XmlTag = "Sections/Sections" + Sections = map(LoadFfsSections, XmlList(XmlFfsSections, XmlTag)) #[ PlatformFfsSectionsClass, ...] + + return PlatformFfsSections + +## Load Platform Ffs Attribute +# +# Read an input Platform XML DOM object and return a platform Ffs Attribute +# contained in the DOM object. +# +# @param XmlFfs An XML DOM object read from FPD file +# +# @retvel List A platform Ffs Attribute loaded from XmlFpd +# +def LoadFfsAttribute(XmlFfs): + List = [] + XmlTag = "Ffs/Attribute" + for XmlAttr in XmlList(XmlFfs, XmlTag): + XmlTag = "Name" + Name = XmlAttribute(XmlAttr, XmlTag) + XmlTag = "Value" + Value = XmlAttribute(XmlAttr, XmlTag) + List.append([Name,Value]) + return List + +## Load a list of Platform Build Options +# +# Read an input Platform XML DOM object and return a list of Build Options +# contained in the DOM object. +# +# @param XmlFfs An XML DOM object read from FPD file +# +# @retvel PlatformFfsKey A platform Ffs key loaded from XmlFpd +# +def LoadPlatformFfs(XmlFfs): + PlatformFfs = PlatformFfsClass() + + PlatformFfs.Attribute = {} + Dict = {} + + List = LoadFfsAttribute(XmlFfs) + + XmlTag = "Ffs/Sections/Sections" + PlatformFfs.Sections = map(LoadPlatformFfsSections, XmlList(XmlFfs, XmlTag)) #[PlatformFfsSectionsClass, ...] + + for Item in List: + Name = Item[0] + Value = Item[1] + for Item in PlatformFfs.Sections: + Dict[(Name, Item)] = Value + PlatformFfs.Attribute = Dict + + XmlTag = "Ffs/FfsKey" + PlatformFfs.Key = XmlAttribute(XmlFfs, XmlTag) + + return PlatformFfs + +## Load a list of Platform Build Options +# +# Read an input Platform XML DOM object and return a list of Build Options +# contained in the DOM object. +# +# @param XmlFpd An XML DOM object read from FPD file +# +# @retvel PlatformBuildOptions A list of Build Options loaded from XmlFpd +# +def LoadPlatformBuildOptions(XmlFpd): + PlatformBuildOptions = PlatformBuildOptionClass() + + PlatformBuildOptions.UserDefinedAntTasks = LoadUserDefinedAntTasks(XmlFpd) + + XmlTag = "PlatformSurfaceArea/BuildOptions/Options/Option" + PlatformBuildOptions.Options = map(LoadBuildOption, XmlList(XmlFpd, XmlTag)) + + PlatformBuildOptions.UserExtensions = LoadPlatformUserExtension(XmlFpd) + + PlatformBuildOptions.FfsKeyList = LoadPlatformFfsDict(XmlFpd) + + return PlatformBuildOptions + +## Load Platform Pcd Data +# +# Read an input Platform XML DOM object and return Platform module class object +# contained in the DOM object. +# +# @param XmlPcd An XML DOM object read from FPD file +# +# @retvel PlatformPcdData A Platform Pcd object loaded from XmlFpd +# +def LoadPlatformPcdData(XmlPcdData): + PcdData = PcdClass() # defined in CommonDataClass.CommonClass.py + + XmlTag = "ItemType" + PcdData.ItemType = XmlAttribute(XmlPcdData, XmlTag) #DYNAMIC + + XmlTag = "PcdData/C_Name" + PcdData.C_NAME = XmlElement(XmlPcdData, XmlTag) + + XmlTag = "PcdData/Token" + PcdData.Token = XmlElement(XmlPcdData, XmlTag) + + XmlTag = "PcdData/TokenSpaceGuidCName" + PcdData.TokenSpaceGuidCName = XmlElement(XmlPcdData, XmlTag) + + XmlTag = "PcdData/DatumType" + PcdData.DatumType = XmlElement(XmlPcdData, XmlTag) + + XmlTag = "PcdData/MaxDatumSize" + PcdData.MaxDatumSize = XmlElement(XmlPcdData, XmlTag) + + XmlTag = "PcdData/Value" + PcdData.Value = XmlElement(XmlPcdData, XmlTag) + + return PcdData + +## Load a Platform Pcd Build Data +# +# Read an input Platform XML DOM object and return a list of Pcd Dynamic +# contained in the DOM object. +# +# @param XmlPcdBuildData An XML DOM object read from FPD file +# +# @retvel PcdBuildData A Platform Pcd Build Data loaded from XmlFpd +# +def LoadPlatformPcdBuildData(XmlPcdBuildData): + PcdBuildData = PcdClass() # defined in CommonDataClass.CommonClass.py + + XmlTag = "ItemType" + PcdBuildData.ItemType = XmlAttribute(XmlPcdBuildData, XmlTag) #DYNAMIC + + XmlTag = "PcdBuildData/C_Name" + PcdBuildData.C_NAME = XmlElement(XmlPcdBuildData, XmlTag) + + XmlTag = "PcdBuildData/Token" + PcdBuildData.Token = XmlElement(XmlPcdBuildData, XmlTag) + + XmlTag = "PcdBuildData/TokenSpaceGuidCName" + PcdBuildData.TokenSpaceGuidCName = XmlElement(XmlPcdBuildData, XmlTag) + + XmlTag = "PcdBuildData/DatumType" + PcdBuildData.DatumType = XmlElement(XmlPcdBuildData, XmlTag) + + XmlTag = "PcdBuildData/MaxDatumSize" + PcdBuildData.MaxDatumSize = XmlElement(XmlPcdBuildData, XmlTag) + + #XmlTag = "PcdBuildData/Value" + #PcdBuildData.Value = XmlElement(XmlPcdBuildData, XmlTag) + + return PcdBuildData + +## Load a list of Platform Pcd Dynamic +# +# Read an input Platform XML DOM object and return a list of Pcd Dynamic +# contained in the DOM object. +# +# @param XmlFpd An XML DOM object read from FPD file +# +# @retvel PcdDynamic A list of Pcd Dynamic loaded from XmlFpd +# +def LoadDynamicPcdBuildDefinitions(XmlFpd): + DynamicPcdBuildDefinitions = [] + XmlTag = "PlatformSurfaceArea/DynamicPcdBuildDefinitions/PcdBuildData" + return map(LoadPlatformPcdBuildData, XmlList(XmlFpd, XmlTag)) + +## Load a Platform NameValue object +# +# Read an input Platform XML DOM object and return a list of User Extensions +# contained in the DOM object. +# +# @param XmlNameValue An XML DOM object read from FPD file +# +# @retvel NameValue A Platform NameValue object +# +def LoadNameValue(XmlNameValue): + NameValue = [] + + XmlTag = "Name" + Name = XmlAttribute(XmlNameValue, XmlTag) + NameValue.append(Name) + + XmlTag = "Value" + Value = XmlAttribute(XmlNameValue, XmlTag) + NameValue.append(Value) + + return NameValue + +## Load a Platform Fv Image Name object +# +# Read an input Platform XML DOM object and return a platform Fv Image +# Name contained in the DOM object. +# +# @param XmlFvImageNames An XML DOM object read from FPD file +# +# @retvel FvImageNames A Platform Fv Image Name object +# +def LoadFvImageNames(XmlFvImageNames): + XmlTag = "FvImageNames" + FvImageNames = XmlElement(XmlFvImageNames, XmlTag) + return FvImageNames + +## Load a Platform Fv Image option object +# +# Read an input Platform XML DOM object and return a platform Fv Image +# Option contained in the DOM object. +# +# @param XmlFvImageOptions An XML DOM object read from FPD file +# +# @retvel PlatformFvImageOption A Platform Fv Image Option object +# +def LoadFvImageOptions(XmlFvImageOptions): + PlatformFvImageOption = PlatformFvImageOptionClass() + + XmlTag = "" + PlatformFvImageOption.FvImageOptionName = '' + + XmlTag = "" + PlatformFvImageOption.FvImageOptionValues = [] + + XmlTag = "FvImageOptions/NameValue" + List = map(LoadNameValue, XmlList(XmlFvImageOptions, XmlTag)) + + return PlatformFvImageOption + +## Load a Platform Fv Image object +# +# Read an input Platform XML DOM object and return a list of User Extensions +# contained in the DOM object. +# +# @param XmlFvImage An XML DOM object read from Fpd file +# +# @retvel PlatformFvImage A Platform Fv Image object +# +def LoadPlatformFvImage(XmlFvImage): + PlatformFvImage = PlatformFvImageClass() + + XmlTag = "Name" + PlatformFvImage.Name = XmlAttribute(XmlFvImage, XmlTag) + + XmlTag = "Value" + PlatformFvImage.Value = XmlAttribute(XmlFvImage, XmlTag) + + XmlTag = "Type" + PlatformFvImage.Type = XmlAttribute(XmlFvImage, XmlTag) + + XmlTag = "FvImage/FvImageNames" + PlatformFvImage.FvImageNames = map(LoadFvImageNames, XmlList(XmlFvImage, XmlTag)) + + XmlTag = "FvImage/FvImageOptions" + PlatformFvImage.FvImageOptions = map(LoadFvImageOptions, XmlList(XmlFvImage, XmlTag)) + + return PlatformFvImage + +## Load a Platform fdf object +# +# Read an input Platform XML DOM object and return a list of User Extensions +# contained in the DOM object. +# +# @param XmlFvImages An XML DOM object read from FPD file +# +# @retvel PlatformFdf A Platform fdf object +# +def LoadPlatformFvImages(XmlFvImages): + List = [] + + XmlTag = "FvImages/NameValue" + NameValues = map(LoadNameValue, XmlList(XmlFvImages, XmlTag)) + List.append(NameValues) + + XmlTag = "FvImages/FvImage" + FvImages = map(LoadPlatformFvImage, XmlList(XmlFvImages, XmlTag)) + List.append(FvImages) + + XmlTag = "FvImages/FvImageName" + FvImageNames = map(LoadPlatformFvImageName, XmlList(XmlFvImages, XmlTag)) + List.append(FvImageNames) + + return List + +## Load a Platform Fv Image Name object +# +# Read an input Platform XML DOM object and return a list of User Extensions +# contained in the DOM object. +# +# @param XmlFvImageName An XML DOM object read from FPD file +# +# @retvel PlatformFvImageName A Platform Fv Image Name object +# +def LoadPlatformFvImageName(XmlFvImageName): + PlatformFvImageName = PlatformFvImageNameClass() + + XmlTag = "Name" + PlatformFvImageName.Name = XmlAttribute(XmlFvImageName, XmlTag) + + XmlTag = "Type" + PlatformFvImageName.Type = XmlAttribute(XmlFvImageName, XmlTag) + + XmlTag = "FvImageOptions" + PlatformFvImageName.FvImageOptions = map(LoadFvImageOptions, XmlList(XmlFvImageName, XmlTag)) + + return PlatformFvImageName + +## Load a list of Platform fdf objects +# +# Read an input Platform XML DOM object and return a list of User Extensions +# contained in the DOM object. +# +# @param XmlFpd An XML DOM object read from FPD file +# +# @retvel PlatformFdfs A list of Platform fdf object +# +def LoadPlatformFdfs(XmlFpd): + PlatformFvImages = PlatformFvImagesClass() + + XmlTag = "PlatformSurfaceArea/Flash/FvImages" + PlatformFvImages.FvImages = map(LoadPlatformFvImages, XmlList(XmlFpd, XmlTag)) + + return PlatformFvImages + +## Load a Platform User Extensions +# +# Read an input Platform XML DOM object and return an User Extension +# contained in the DOM object. +# +# @param XmlUserExtension An XML DOM object read from FPD file +# +# @retvel PlatformUserExtensions A platform User Extension loaded from XmlFpd +# +def LoadPlatformUserExtension(XmlFpd): + Dict = {} + + PlatformUserExtensions = UserExtensionsClass() + + XmlTag = "PlatformSurfaceArea/BuildOptions/UserExtensions" + List = map(LoadUserExtensions, XmlList(XmlFpd, XmlTag)) + if List != []: + for Item in List: + UserID = Item.UserID + Identifier = Item.Identifier + Dict[(UserID, Identifier)] = Item + #XmlTag = "PlatformSurfaceArea/BuildOptions/UserExtensions/UserID" + #PlatformUserExtensions.UserID = XmlAttribute(XmlFpd, XmlTag) + + #XmlTag = "PlatformSurfaceArea/BuildOptions/UserExtensions/Identifier" + #PlatformUserExtensions.Identifier = XmlAttribute(XmlFpd, XmlTag) + + #PlatformUserExtensions.Content = XmlElementData(XmlFpd) + #Dict[(PlatformUserExtensions.UserID,PlatformUserExtensions.Identifier)] = PlatformUserExtensions + #return PlatformUserExtensions + return Dict + +## Load a list of Platform User Extensions +# +# Read an input Platform XML DOM object and return a list of User Extensions +# contained in the DOM object. +# +# @param XmlFpd An XML DOM object read from FPD file +# +# @retvel UserExtensions A list of platform User Extensions loaded from XmlFpd +# +def LoadPlatformUserExtensions(XmlFpd): + XmlTag = "PlatformSurfaceArea/UserExtensions" + return map(LoadUserExtensions, XmlList(XmlFpd, XmlTag)) # from MigrationUtilities.py LoadUserExtensions + +## Load a new Platform class object +# +# Read an input FPD File and return a new Platform class Object. +# +# @param FpdFileName An XML DOM object read from FPD file +# +# @retvel Platform A new Platform class object loaded from FPD File +# +def LoadFpd(FpdFileName): + XmlFpd = XmlParseFile(FpdFileName) + EdkLogger.verbose("Load FPD File: %s" % FpdFileName) + + Platform = PlatformClass() + Platform.Header = LoadPlatformHeader(XmlFpd, FpdFileName) + Platform.SkuInfos = LoadPlatformSkuInfos(XmlFpd) + Platform.Libraries = [] #New in dsc spec, do not handle for now + Platform.LibraryClasses = LoadPlatformLibraryClasses(XmlFpd) + Platform.Modules = LoadPlatformModules(XmlFpd) + Platform.FlashDefinitionFile = LoadPlatformFlashDefinitionFile(XmlFpd, FpdFileName) + Platform.BuildOptions = LoadPlatformBuildOptions(XmlFpd) + Platform.DynamicPcdBuildDefinitions = LoadDynamicPcdBuildDefinitions(XmlFpd) + Platform.Fdf = LoadPlatformFdfs(XmlFpd) + Platform.UserExtensions = LoadPlatformUserExtensions(XmlFpd) + + return Platform + +# This acts like the main() function for the script, unless it is 'import'ed +# into another script. +if __name__ == '__main__': + pass \ No newline at end of file diff --git a/BaseTools/Source/Python/fpd2dsc/MigrationUtilities.py b/BaseTools/Source/Python/fpd2dsc/MigrationUtilities.py new file mode 100644 index 0000000000..d3c724832c --- /dev/null +++ b/BaseTools/Source/Python/fpd2dsc/MigrationUtilities.py @@ -0,0 +1,563 @@ +## @file +# Contains several utilitities shared by migration tools. +# +# Copyright (c) 2007, 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 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 re +import EdkLogger +from optparse import OptionParser +from Common.BuildToolError import * +from XmlRoutines import * +from CommonDataClass.CommonClass import * + +## Set all fields of CommonClass object. +# +# Set all attributes of CommonClass object from XML Dom object of XmlCommon. +# +# @param Common The destine CommonClass object. +# @param XmlCommon The source XML Dom object. +# +def SetCommon(Common, XmlCommon): + XmlTag = "Usage" + Common.Usage = XmlAttribute(XmlCommon, XmlTag).split() + + XmlTag = "FeatureFlag" + Common.FeatureFlag = XmlAttribute(XmlCommon, XmlTag) + + XmlTag = "SupArchList" + Common.SupArchList = XmlAttribute(XmlCommon, XmlTag).split() + + XmlTag = XmlNodeName(XmlCommon) + "/" + "HelpText" + Common.HelpText = XmlElement(XmlCommon, XmlTag) + + +## Set some fields of CommonHeaderClass object. +# +# Set Name, Guid, FileName and FullPath fields of CommonHeaderClass object from +# XML Dom object of XmlCommonHeader, NameTag and FileName. +# +# @param CommonHeader The destine CommonClass object. +# @param XmlCommonHeader The source XML Dom object. +# @param NameTag The name tag in XML Dom object. +# @param FileName The file name of the XML file. +# +def SetIdentification(CommonHeader, XmlCommonHeader, NameTag, FileName): + XmlParentTag = XmlNodeName(XmlCommonHeader) + + XmlTag = XmlParentTag + "/" + NameTag + CommonHeader.Name = XmlElement(XmlCommonHeader, XmlTag) + + XmlTag = XmlParentTag + "/" + "GuidValue" + CommonHeader.Guid = XmlElement(XmlCommonHeader, XmlTag) + + XmlTag = XmlParentTag + "/" + "Version" + CommonHeader.Version = XmlElement(XmlCommonHeader, XmlTag) + + CommonHeader.FileName = os.path.basename(FileName) + CommonHeader.FullPath = os.path.abspath(FileName) + + +## Regular expression to match specification and value. +mReSpecification = re.compile(r"(?P\w+)\s+(?P\w*)") + +## Add specification to specification dictionary. +# +# Abstract specification name, value pair from Specification String and add them +# to specification dictionary. +# +# @param SpecificationDict The destine Specification dictionary. +# @param SpecificationString The source Specification String from which the +# specification name and value pair is abstracted. +# +def AddToSpecificationDict(SpecificationDict, SpecificationString): + """Abstract specification name, value pair from Specification String""" + for SpecificationMatch in mReSpecification.finditer(SpecificationString): + Specification = SpecificationMatch.group("Specification") + Value = SpecificationMatch.group("Value") + SpecificationDict[Specification] = Value + +## Set all fields of CommonHeaderClass object. +# +# Set all attributes of CommonHeaderClass object from XML Dom object of +# XmlCommonHeader, NameTag and FileName. +# +# @param CommonHeader The destine CommonClass object. +# @param XmlCommonHeader The source XML Dom object. +# @param NameTag The name tag in XML Dom object. +# @param FileName The file name of the XML file. +# +def SetCommonHeader(CommonHeader, XmlCommonHeader): + """Set all attributes of CommonHeaderClass object from XmlCommonHeader""" + XmlParent = XmlNodeName(XmlCommonHeader) + + XmlTag = XmlParent + "/" + "Abstract" + CommonHeader.Abstract = XmlElement(XmlCommonHeader, XmlTag) + + XmlTag = XmlParent + "/" + "Description" + CommonHeader.Description = XmlElement(XmlCommonHeader, XmlTag) + + XmlTag = XmlParent + "/" + "Copyright" + CommonHeader.Copyright = XmlElement(XmlCommonHeader, XmlTag) + + XmlTag = XmlParent + "/" + "License" + CommonHeader.License = XmlElement(XmlCommonHeader, XmlTag) + + XmlTag = XmlParent + "/" + "Specification" + Specification = XmlElement(XmlCommonHeader, XmlTag) + + AddToSpecificationDict(CommonHeader.Specification, Specification) + + XmlTag = XmlParent + "/" + "ModuleType" + CommonHeader.ModuleType = XmlElement(XmlCommonHeader, XmlTag) + + +## Load a new Cloned Record class object. +# +# Read an input XML ClonedRecord DOM object and return an object of Cloned Record +# contained in the DOM object. +# +# @param XmlCloned A child XML DOM object in a Common XML DOM. +# +# @retvel ClonedRecord A new Cloned Record object created by XmlCloned. +# +def LoadClonedRecord(XmlCloned): + ClonedRecord = ClonedRecordClass() + + XmlTag = "Id" + ClonedRecord.Id = int(XmlAttribute(XmlCloned, XmlTag)) + + XmlTag = "FarGuid" + ClonedRecord.FarGuid = XmlAttribute(XmlCloned, XmlTag) + + XmlTag = "Cloned/PackageGuid" + ClonedRecord.PackageGuid = XmlElement(XmlCloned, XmlTag) + + XmlTag = "Cloned/PackageVersion" + ClonedRecord.PackageVersion = XmlElement(XmlCloned, XmlTag) + + XmlTag = "Cloned/ModuleGuid" + ClonedRecord.ModuleGuid = XmlElement(XmlCloned, XmlTag) + + XmlTag = "Cloned/ModuleVersion" + ClonedRecord.ModuleVersion = XmlElement(XmlCloned, XmlTag) + + return ClonedRecord + + +## Load a new Guid/Protocol/Ppi common class object. +# +# Read an input XML Guid/Protocol/Ppi DOM object and return an object of +# Guid/Protocol/Ppi contained in the DOM object. +# +# @param XmlGuidProtocolPpiCommon A child XML DOM object in a Common XML DOM. +# +# @retvel GuidProtocolPpiCommon A new GuidProtocolPpiCommon class object +# created by XmlGuidProtocolPpiCommon. +# +def LoadGuidProtocolPpiCommon(XmlGuidProtocolPpiCommon): + GuidProtocolPpiCommon = GuidProtocolPpiCommonClass() + + XmlTag = "Name" + GuidProtocolPpiCommon.Name = XmlAttribute(XmlGuidProtocolPpiCommon, XmlTag) + + XmlParent = XmlNodeName(XmlGuidProtocolPpiCommon) + if XmlParent == "Entry": + XmlTag = "%s/C_Name" % XmlParent + elif XmlParent == "GuidCNames": + XmlTag = "%s/GuidCName" % XmlParent + else: + XmlTag = "%s/%sCName" % (XmlParent, XmlParent) + + GuidProtocolPpiCommon.CName = XmlElement(XmlGuidProtocolPpiCommon, XmlTag) + + XmlTag = XmlParent + "/" + "GuidValue" + GuidProtocolPpiCommon.Guid = XmlElement(XmlGuidProtocolPpiCommon, XmlTag) + + if XmlParent.endswith("Notify"): + GuidProtocolPpiCommon.Notify = True + + XmlTag = "GuidTypeList" + GuidTypes = XmlAttribute(XmlGuidProtocolPpiCommon, XmlTag) + GuidProtocolPpiCommon.GuidTypeList = GuidTypes.split() + + XmlTag = "SupModuleList" + SupModules = XmlAttribute(XmlGuidProtocolPpiCommon, XmlTag) + GuidProtocolPpiCommon.SupModuleList = SupModules.split() + + SetCommon(GuidProtocolPpiCommon, XmlGuidProtocolPpiCommon) + + return GuidProtocolPpiCommon + + +## Load a new Pcd class object. +# +# Read an input XML Pcd DOM object and return an object of Pcd +# contained in the DOM object. +# +# @param XmlPcd A child XML DOM object in a Common XML DOM. +# +# @retvel Pcd A new Pcd object created by XmlPcd. +# +def LoadPcd(XmlPcd): + """Return a new PcdClass object equivalent to XmlPcd""" + Pcd = PcdClass() + + XmlTag = "PcdEntry/C_Name" + Pcd.CName = XmlElement(XmlPcd, XmlTag) + + XmlTag = "PcdEntry/Token" + Pcd.Token = XmlElement(XmlPcd, XmlTag) + + XmlTag = "PcdEntry/TokenSpaceGuidCName" + Pcd.TokenSpaceGuidCName = XmlElement(XmlPcd, XmlTag) + + XmlTag = "PcdEntry/DatumType" + Pcd.DatumType = XmlElement(XmlPcd, XmlTag) + + XmlTag = "PcdEntry/MaxDatumSize" + Pcd.MaxDatumSize = XmlElement(XmlPcd, XmlTag) + + XmlTag = "PcdEntry/DefaultValue" + Pcd.DefaultValue = XmlElement(XmlPcd, XmlTag) + + XmlTag = "PcdItemType" + Pcd.ItemType = XmlAttribute(XmlPcd, XmlTag) + + XmlTag = "PcdEntry/ValidUsage" + Pcd.ValidUsage = XmlElement(XmlPcd, XmlTag).split() + + XmlTag = "SupModuleList" + Pcd.SupModuleList = XmlAttribute(XmlPcd, XmlTag).split() + + SetCommon(Pcd, XmlPcd) + + return Pcd + + +## Load a new LibraryClass class object. +# +# Read an input XML LibraryClass DOM object and return an object of LibraryClass +# contained in the DOM object. +# +# @param XmlLibraryClass A child XML DOM object in a Common XML DOM. +# +# @retvel LibraryClass A new LibraryClass object created by XmlLibraryClass. +# +def LoadLibraryClass(XmlLibraryClass): + LibraryClass = LibraryClassClass() + + XmlTag = "LibraryClass/Keyword" + LibraryClass.LibraryClass = XmlElement(XmlLibraryClass, XmlTag) + if LibraryClass.LibraryClass == "": + XmlTag = "Name" + LibraryClass.LibraryClass = XmlAttribute(XmlLibraryClass, XmlTag) + + XmlTag = "LibraryClass/IncludeHeader" + LibraryClass.IncludeHeader = XmlElement(XmlLibraryClass, XmlTag) + + XmlTag = "RecommendedInstanceVersion" + RecommendedInstanceVersion = XmlAttribute(XmlLibraryClass, XmlTag) + LibraryClass.RecommendedInstanceVersion = RecommendedInstanceVersion + + XmlTag = "RecommendedInstanceGuid" + RecommendedInstanceGuid = XmlAttribute(XmlLibraryClass, XmlTag) + LibraryClass.RecommendedInstanceGuid = RecommendedInstanceGuid + + XmlTag = "SupModuleList" + SupModules = XmlAttribute(XmlLibraryClass, XmlTag) + LibraryClass.SupModuleList = SupModules.split() + + SetCommon(LibraryClass, XmlLibraryClass) + + return LibraryClass + + +## Load a new Build Option class object. +# +# Read an input XML BuildOption DOM object and return an object of Build Option +# contained in the DOM object. +# +# @param XmlBuildOption A child XML DOM object in a Common XML DOM. +# +# @retvel BuildOption A new Build Option object created by XmlBuildOption. +# +def LoadBuildOption(XmlBuildOption): + """Return a new BuildOptionClass object equivalent to XmlBuildOption""" + BuildOption = BuildOptionClass() + + BuildOption.Option = XmlElementData(XmlBuildOption) + + XmlTag = "BuildTargets" + BuildOption.BuildTargetList = XmlAttribute(XmlBuildOption, XmlTag).split() + + XmlTag = "ToolChainFamily" + BuildOption.ToolChainFamily = XmlAttribute(XmlBuildOption, XmlTag) + + XmlTag = "TagName" + BuildOption.TagName = XmlAttribute(XmlBuildOption, XmlTag) + + XmlTag = "ToolCode" + BuildOption.ToolCode = XmlAttribute(XmlBuildOption, XmlTag) + + XmlTag = "SupArchList" + BuildOption.SupArchList = XmlAttribute(XmlBuildOption, XmlTag).split() + + return BuildOption + + +## Load a new User Extensions class object. +# +# Read an input XML UserExtensions DOM object and return an object of User +# Extensions contained in the DOM object. +# +# @param XmlUserExtensions A child XML DOM object in a Common XML DOM. +# +# @retvel UserExtensions A new User Extensions object created by +# XmlUserExtensions. +# +def LoadUserExtensions(XmlUserExtensions): + UserExtensions = UserExtensionsClass() + + XmlTag = "UserId" + UserExtensions.UserID = XmlAttribute(XmlUserExtensions, XmlTag) + + XmlTag = "Identifier" + UserExtensions.Identifier = XmlAttribute(XmlUserExtensions, XmlTag) + + UserExtensions.Content = XmlElementData(XmlUserExtensions) + + return UserExtensions + + +## Store content to a text file object. +# +# Write some text file content to a text file object. The contents may echo +# in screen in a verbose way. +# +# @param TextFile The text file object. +# @param Content The string object to be written to a text file. +# +def StoreTextFile(TextFile, Content): + EdkLogger.verbose(Content) + TextFile.write(Content) + + +## Add item to a section. +# +# Add an Item with specific CPU architecture to section dictionary. +# The possible duplication is ensured to be removed. +# +# @param Section Section dictionary indexed by CPU architecture. +# @param Arch CPU architecture: Ia32, X64, Ipf, Ebc or Common. +# @param Item The Item to be added to section dictionary. +# +def AddToSection(Section, Arch, Item): + SectionArch = Section.get(Arch, []) + if Item not in SectionArch: + SectionArch.append(Item) + Section[Arch] = SectionArch + + +## Get section contents. +# +# Return the content of section named SectionName. +# the contents is based on Methods and ObjectLists. +# +# @param SectionName The name of the section. +# @param Method A function returning a string item of an object. +# @param ObjectList The list of object. +# +# @retval Section The string content of a section. +# +def GetSection(SectionName, Method, ObjectList): + SupportedArches = ["common", "Ia32", "X64", "Ipf", "Ebc"] + SectionDict = {} + for Object in ObjectList: + Item = Method(Object) + if Item == "": + continue + Item = " %s" % Item + Arches = Object.SupArchList + if len(Arches) == 0: + AddToSection(SectionDict, "common", Item) + else: + for Arch in SupportedArches: + if Arch.upper() in Arches: + AddToSection(SectionDict, Arch, Item) + + Section = "" + for Arch in SupportedArches: + SectionArch = "\n".join(SectionDict.get(Arch, [])) + if SectionArch != "": + Section += "[%s.%s]\n%s\n" % (SectionName, Arch, SectionArch) + Section += "\n" + if Section != "": + Section += "\n" + return Section + + +## Store file header to a text file. +# +# Write standard file header to a text file. The content includes copyright, +# abstract, description and license extracted from CommonHeader class object. +# +# @param TextFile The text file object. +# @param CommonHeader The source CommonHeader class object. +# +def StoreHeader(TextFile, CommonHeader): + CopyRight = CommonHeader.Copyright + Abstract = CommonHeader.Abstract + Description = CommonHeader.Description + License = CommonHeader.License + + Header = "#/** @file\n#\n" + Header += "# " + Abstract + "\n#\n" + Header += "# " + Description.strip().replace("\n", "\n# ") + "\n" + Header += "# " + CopyRight + "\n#\n" + Header += "# " + License.replace("\n", "\n# ").replace(" ", " ") + Header += "\n#\n#**/\n\n" + + StoreTextFile(TextFile, Header) + +## Store file header to a text file. +# +# Write Defines section to a text file. DefinesTupleList determines the content. +# +# @param TextFile The text file object. +# @param DefinesTupleList The list of (Tag, Value) to be added as one item. +# +def StoreDefinesSection(TextFile, DefinesTupleList): + Section = "[Defines]\n" + for DefineItem in DefinesTupleList: + Section += " %-30s = %s\n" % DefineItem + + Section += "\n\n" + StoreTextFile(TextFile, Section) + + +## Add item to PCD dictionary. +# +# Add an PcdClass object to PCD dictionary. The key is generated from +# PcdItemType. +# +# @param PcdDict PCD dictionary indexed by Pcd Item Type. +# @param Arch CPU architecture: Ia32, X64, Ipf, Ebc or Common. +# @param Item The Item to be added to section dictionary. +# +def AddToPcdsDict(PcdDict, PcdItemType, PcdCode): + PcdSectionName = PcdItemType + PcdSectionName = PcdSectionName.title() + PcdSectionName = PcdSectionName.replace("_", "") + PcdSectionName = "Pcds" + PcdSectionName + PcdDict.setdefault(PcdSectionName, []).append(PcdCode) + +## Regular expression to match an equation. +mReEquation = re.compile(r"\s*(\S+)\s*=\s*(\S*)\s*") + +## Return a value tuple matching information in a text fle. +# +# Parse the text file and return a value tuple corresponding to an input tag +# tuple. In case of any error, an tuple of empty strings is returned. +# +# @param FileName The file name of the text file. +# @param TagTuple A tuple of tags as the key to the value. +# +# @param ValueTupe The returned tuple corresponding to the tag tuple. +# +def GetTextFileInfo(FileName, TagTuple): + ValueTuple = [""] * len(TagTuple) + try: + for Line in open(FileName): + Line = Line.split("#", 1)[0] + MatchEquation = mReEquation.match(Line) + if MatchEquation: + Tag = MatchEquation.group(1).upper() + Value = MatchEquation.group(2) + for Index in range(len(TagTuple)): + if TagTuple[Index] == Tag: + ValueTuple[Index] = Value + except: + EdkLogger.info("IO Error in reading file %s" % FileName) + + return ValueTuple + +## Return a value tuple matching information in an XML fle. +# +# Parse the XML file and return a value tuple corresponding to an input tag +# tuple. In case of any error, an tuple of empty strings is returned. +# +# @param FileName The file name of the XML file. +# @param TagTuple A tuple of tags as the key to the value. +# +# @param ValueTupe The returned tuple corresponding to the tag tuple. +# +def GetXmlFileInfo(FileName, TagTuple): + XmlDom = XmlParseFile(FileName) + return tuple([XmlElement(XmlDom, XmlTag) for XmlTag in TagTuple]) + +# Version and Copyright +__version_number__ = "1.0" +__version__ = "%prog Version " + __version_number__ +__copyright__ = "Copyright (c) 2007, Intel Corporation. All rights reserved." + +## Parse migration command line options +# +# Use standard Python module optparse to parse command line option of this tool. +# +# @param Source The source file type. +# @param Destinate The destinate file type. +# +# @retval Options A optparse object containing the parsed options. +# @retval InputFile Path of an source file to be migrated. +# +def MigrationOptionParser(Source, Destinate): + # use clearer usage to override default usage message + UsageString = "%prog [-a] [-o ] " + + Parser = OptionParser(description=__copyright__, version=__version__, usage=UsageString) + + HelpText = "The name of the %s file to be created." % Destinate + Parser.add_option("-o", "--output", dest="OutputFile", help=HelpText) + + HelpText = "Automatically create the %s file using the name of the %s file and replacing file extension" % (Source, Destinate) + Parser.add_option("-a", "--auto", dest="AutoWrite", action="store_true", default=False, help=HelpText) + + Options, Args = Parser.parse_args() + + # error check + if len(Args) == 0: + raise MigrationError(OPTION_MISSING, name="Input file", usage=Parser.get_usage()) + if len(Args) > 1: + raise MigrationError(OPTION_NOT_SUPPORTED, name="Too many input files", usage=Parser.get_usage()) + + InputFile = Args[0] + if not os.path.exists(InputFile): + raise MigrationError(FILE_NOT_FOUND, name=InputFile) + + if Options.OutputFile: + if Options.AutoWrite: + raise MigrationError(OPTION_CONFLICT, arg1="-o", arg2="-a", usage=Parser.get_usage()) + else: + if Options.AutoWrite: + Options.OutputFile = os.path.splitext(InputFile)[0] + "." + Destinate.lower() + else: + raise MigrationError(OPTION_MISSING, name="-o", usage=Parser.get_usage()) + + return Options, InputFile + +# This acts like the main() function for the script, unless it is 'import'ed +# into another script. +if __name__ == '__main__': + pass diff --git a/BaseTools/Source/Python/fpd2dsc/StoreDsc.py b/BaseTools/Source/Python/fpd2dsc/StoreDsc.py new file mode 100644 index 0000000000..8d07ab9c5b --- /dev/null +++ b/BaseTools/Source/Python/fpd2dsc/StoreDsc.py @@ -0,0 +1,765 @@ +## @file +# Store a Platform class object to an INF file. +# +# Copyright (c) 2007 - 2009, 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 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 +# +from LoadFpd import LoadFpd +from CommonDataClass.PlatformClass import * +from CommonDataClass.FdfClass import * +from Common.MigrationUtilities import * +from Common.ToolDefClassObject import * +from Common.TargetTxtClassObject import * + +## Store Defines section +# +# Write [Defines] section to the DscFile based on Platform class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param DscFile The output DSC file to store the Defines section +# @param Platform An input Platform class object +# +def StorePlatformDefinesSection(DscFile, Platform): + PlatformHeader = Platform.Header + + DefinesTupleList = [] + + if PlatformHeader.Name != "": + DefinesTupleList.append(("PLATFORM_NAME", PlatformHeader.Name)) + + if PlatformHeader.Guid != "": + DefinesTupleList.append(("PLATFORM_GUID", PlatformHeader.Guid)) + + if PlatformHeader.Version != "": + DefinesTupleList.append(("PLATFORM_VERSION", PlatformHeader.Version)) + for key in PlatformHeader.Specification.keys(): + SpecificationValue = PlatformHeader.Specification.get(key) + DefinesTupleList.append(("DSC_ SPECIFICATION", SpecificationValue)) + + if PlatformHeader.OutputDirectory != "": + DefinesTupleList.append(("OUTPUT_DIRECTORY", PlatformHeader.OutputDirectory)) + + if PlatformHeader.SupArchList != "": + String = "|".join(PlatformHeader.SupArchList) + DefinesTupleList.append(("SUPPORTED_ARCHITECTURES", String)) + + if PlatformHeader.BuildTargets != "": + String = "|".join(PlatformHeader.BuildTargets) + DefinesTupleList.append(("BUILD_TARGETS", String)) + + if PlatformHeader.SkuIdName != "": + #DefinesTupleList.append(("SKUID_IDENTIFIER", PlatformHeader.SkuIdName)) + String = "|".join(PlatformHeader.SkuIdName) + if String != "": + DefinesTupleList.append(("SKUID_IDENTIFIER", String)) + + String = Platform.FlashDefinitionFile.FilePath + if String != "": + DefinesTupleList.append(("FLASH_DEFINITION", String)) + + List = [] + List.append("################################################################################") + List.append("#") + List.append("# Defines Section - statements that will be processed to create a Makefile.") + List.append("#") + List.append("################################################################################") + Section = "\n".join(List) + Section += "\n" + StoreTextFile(DscFile, Section) + + StoreDefinesSection(DscFile, DefinesTupleList) + +## Store SkuIds section +# +# Write [SkuIds] section to the DscFile based on Platform class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param DscFile The output DSC file to store the Library Classes section +# @param Platform An input Platform class object +# +def StorePlatformSkuIdsSection(DscFile, Platform): + List = [] + List.append("################################################################################") + List.append("#") + List.append("# SKU Identification section - list of all SKU IDs supported by this Platform.") + List.append("#") + List.append("################################################################################") + Section = "\n".join(List) + Section += "\n" + + Section += "[SkuIds]" + '\n' + + List = Platform.SkuInfos.SkuInfoList + for Item in List: + Section = Section + "%s" % Item[0] + '|' + "%s" % Item[1] + '\n' + Section = Section + '\n' + + StoreTextFile(DscFile, Section) + +## Store Build Options section +# +# Write [BuildOptions] section to the DscFile based on Platform class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param DscFile The output DSC file to store the Build Options section +# @param Platform An input Platform class object +# +def StorePlatformBuildOptionsSection(DscFile, Platform): + # which is from tools_def.txt + StandardBuildTargets = ["DEBUG", "RELEASE"] + SupportedArches = ["COMMON", "IA32", "X64", "IPF", "EBC", "ARM"] + Target = TargetTxtClassObject() + WorkSpace = os.getenv('WORKSPACE') + Target.LoadTargetTxtFile(WorkSpace + '\\Conf\\target.txt') + ToolDef = ToolDefClassObject() + ToolDef.LoadToolDefFile(WorkSpace + '\\' + Target.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]) + # Now we have got ToolDef object + #ToolDef.ToolsDefTxtDictionary + Dict = ToolDef.ToolsDefTxtDatabase + + Dict1 = ToolDef.ToolsDefTxtDictionary # we care the info in this Dict + # + # We only support *(DEBUG/RELEASE) and *(All Arch: IA32, X64, IPF and EBC) for now + # + SectionWINDDK = '' + SectionVS2003 = '' + SectionVS2005EXP = '' + SectionVS2005STD = '' + SectionVS2005PRO = '' + SectionVS2005TEAMSUITE = '' + SectionUNIXGCC = '' + SectionCYGWINGCC = '' + SectionELFGCC = '' + SectionICC = '' + SectionMYTOOLS = '' + for key in Dict1.keys(): + if key.find("_CC_FLAGS") != -1: + if key.find('WINDDK3790x1830') != -1: + SectionWINDDK = " = " + Dict1.get(key) + "\n" + elif key.find('VS2003') != -1: + SectionVS2003 = " = " + Dict1.get(key)+ "\n" + elif key.find('VS2005EXP') != -1: + SectionVS2005EXP = " = " + Dict1.get(key) + "\n" + elif key.find('VS2005STD') != -1: + SectionVS2005STD = " = " + Dict1.get(key) + "\n" + elif key.find('VS2005PRO') != -1: + SectionVS2005PRO = " = " + Dict1.get(key) + "\n" + elif key.find('VS2005TEAMSUITE') != -1: + SectionVS2005TEAMSUITE = " = " + Dict1.get(key) + "\n" + elif key.find('UNIXGCC') != -1: + SectionUNIXGCC = " = " + Dict1.get(key) + "\n" + elif key.find('CYGWINGCC') != -1: + SectionCYGWINGCC = " = " + Dict1.get(key) + "\n" + elif key.find('ELFGCC') != -1: + SectionELFGCC = " = " + Dict1.get(key) + "\n" + elif key.find('ICC') != -1: + SectionICC = " = " + Dict1.get(key) + "\n" + elif key.find('MYTOOLS') != -1: + SectionMYTOOLS = " = " + Dict1.get(key) + "\n" + else: + print "Error!" + + # + # First need to check which arch + # + Archs = Platform.Header.SupArchList + BuildTargets = Platform.Header.BuildTargets + #if BuildTargets == StandardBuildTargets: + #print "Debug and Release both support" # skip debug/release string search + #else: + #print "need to search debug/release string" + + if len(Archs) == 4: + Arch = "*" + SectionName = "[BuildOptions.Common]\n" + else: + for Arch in Archs: + if Arch == 'IA32': + SectionName = "[BuildOptions.IA32]\n" + elif Arch == 'X64': + SectionName = "[BuildOptions.X64]\n" + elif Arch == 'IPF': + SectionName = "[BuildOptions.IPF]\n" + elif Arch == 'EBC': + SectionName = "[BuildOptions.EBC]\n" + else: + print 'Error!' + Section = "" + if SectionWINDDK != "": + SectionWINDDK = "*_WINDDK3790x1830_" + Arch + "_CC_FLAGS" + SectionWINDDK + Section += SectionWINDDK + if SectionVS2003 != "": + SectionVS2003 = "*_VS2003_" + Arch + "_CC_FLAGS" + SectionVS2003 + Section += SectionVS2003 + if SectionVS2005EXP != "": + SectionVS2005EXP = "*_VS2005EXP_" + Arch + "_CC_FLAGS" + SectionVS2005EXP + Section += SectionVS2005EXP + if SectionVS2005STD != "": + SectionVS2005STD = "*_VS2005STD_" + Arch + "_CC_FLAGS" + SectionVS2005STD + Section += SectionVS2005STD + if SectionVS2005PRO != "": + SectionVS2005PRO = "*_VS2005PRO_" + Arch + "_CC_FLAGS" + SectionVS2005PRO + Section += SectionVS2005PRO + if SectionVS2005TEAMSUITE != "": + SectionVS2005TEAMSUITE = "*_VS2005TEAMSUITE_" + Arch + "_CC_FLAGS" + SectionVS2005TEAMSUITE + Section += SectionVS2005TEAMSUITE + if SectionUNIXGCC != "": + SectionUNIXGCC = "*_UNIXGCC_" + Arch + "_CC_FLAGS" + SectionUNIXGCC + Section += SectionUNIXGCC + if SectionCYGWINGCC != "": + SectionCYGWINGCC = "*_CYGWINGCC_" + Arch + "_CC_FLAGS" + SectionCYGWINGCC + Section += SectionCYGWINGCC + if SectionELFGCC != "": + SectionELFGCC = "*_ELFGCC_" + Arch + "_CC_FLAGS" + SectionELFGCC + Section += SectionELFGCC + if SectionICC != "": + SectionICC = "*_ICC_" + Arch + "_CC_FLAGS" + SectionICC + Section += SectionICC + if SectionMYTOOLS != "": + SectionMYTOOLS = "*_MYTOOLS_" + Arch + "_CC_FLAGS" + SectionMYTOOLS + Section += SectionMYTOOLS + + List = [] + List.append("################################################################################") + List.append("#") + List.append("# Build Options section - list of all Build Options supported by this Platform.") + List.append("#") + List.append("################################################################################") + SectionHeader = "\n".join(List) + SectionHeader += "\n" + + Section = SectionHeader + SectionName + Section + Section += "\n" + StoreTextFile(DscFile, Section) + +## Store Libraries section +# +# Write [Libraries] section to the DscFile based on Platform class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param DscFile The output DSC file to store the Library Classes section +# @param Platform An input Platform class object +# +def StorePlatformLibrariesSection(DscFile,Platform): + List = [] + List.append("################################################################################") + List.append("#") + List.append("# Libraries section - list of all Libraries needed by this Platform.") + List.append("#") + List.append("################################################################################") + SectionHeader = "\n".join(List) + SectionHeader += "\n" + + Section = SectionHeader + '[Libraries]\n\n' + StoreTextFile(DscFile, Section) + +## Return a Platform Library Class Item +# +# Read the input LibraryClass class object and return one line of Library Class Item. +# +# @param LibraryClass An input LibraryClass class object +# +# @retval LibraryClassItem A Module Library Class Item +# +def GetPlatformLibraryClassItem(LibraryClass): + LibraryClassList = [] + LibraryClassList.append(LibraryClass.Name) + LibraryClassList.append(LibraryClass.FilePath) + + return "|$(WORKSPACE)/".join(LibraryClassList).rstrip("|") + +## Add item to a LibraryClass section +# +# Add an Item with specific Module Type to section dictionary. +# The possible duplication is ensured to be removed. +# +# @param Section Section dictionary indexed by CPU architecture +# @param SupModuleList LibraryClass SupModuleList: BASE, SEC, PEI_CORE, PEIM, etc +# @param Item The Item to be added to section dictionary +# +def AddToLibraryClassSection(Section, SupModuleList, Item): + for ModuleType in SupModuleList: + SectionModule = Section.get(ModuleType, []) + if Item not in SectionModule: + SectionModule.append(Item) + Section[ModuleType] = SectionModule + +## Get Library Classes section contents +# +# Return the content of section named SectionName. +# the contents is based on Methods and ObjectLists. +# +# @param SectionName The name of the section +# @param Method A function returning a string item of an object +# @param ObjectList The list of object +# +# @retval Section The string content of a section +# +def GetLibraryClassesSection(SectionName, Method, ObjectList): + SupportedArches = ["COMMON", "IA32", "X64", "IPF", "EBC"] + ModuleTypes = ["BASE","SEC","PEI_CORE","PEIM","DXE_CORE","DXE_DRIVER","DXE_SMM_DRIVER","DXE_SAL_DRIVER","DXE_RUNTIME_DRIVER","UEFI_DRIVER","UEFI_APPLICATION"] + SectionCommonDict = {} + SectionIA32Dict = {} + SectionX64Dict = {} + SectionIPFDict = {} + SectionEBCDict = {} + #ObjectList = list(set(ObjectList)) # delete the same element in the list + for Object in ObjectList: + if Object == None: + continue + Item = Method(Object) + if Item == "": + continue + Item = " %s" % Item + Arches = Object.SupArchList + if len(Arches) == 4: + ModuleType = Object.ModuleType + # [LibraryClasses.Common.ModuleType] + if ModuleType == "BASE": + SupModuleList = ["BASE"] + AddToLibraryClassSection(SectionCommonDict, SupModuleList, Item) + else: + # + SupModuleList = Object.SupModuleList + #AddToSection(SectionDict, "|".join(SupModuleList), Item) + AddToLibraryClassSection(SectionCommonDict, SupModuleList, Item) + else: + # Arch + for Arch in SupportedArches: + if Arch.upper() in Arches: + if Arch == "IA32": + # [LibraryClasses.IA32.ModuleType] + ModuleType = Object.ModuleType + if ModuleType == "BASE": + SupModuleList = ["BASE"] + AddToLibraryClassSection(SectionIA32Dict, SupModuleList, Item) + else: + SupModuleList = Object.SupModuleList + AddToLibraryClassSection(SectionIA32Dict, SupModuleList, Item) + elif Arch == "X64": + # [LibraryClasses.X64.ModuleType] + ModuleType = Object.ModuleType + if ModuleType == "BASE": + SupModuleList = ["BASE"] + AddToLibraryClassSection(SectionX64Dict, SupModuleList, Item) + else: + SupModuleList = Object.SupModuleList + AddToLibraryClassSection(SectionX64Dict, SupModuleList, Item) + elif Arch == "IPF": + # [LibraryClasses.IPF.ModuleType] + ModuleType = Object.ModuleType + if ModuleType == "BASE": + SupModuleList = ["BASE"] + AddToLibraryClassSection(SectionIPFDict, SupModuleList, Item) + else: + SupModuleList = Object.SupModuleList + AddToLibraryClassSection(SectionIPFDict, SupModuleList, Item) + elif Arch == "EBC": + # [LibraryClasses.EBC.ModuleType] + ModuleType = Object.ModuleType + if ModuleType == "BASE": + SupModuleList = ["BASE"] + AddToLibraryClassSection(SectionEBCDict, SupModuleList, Item) + else: + SupModuleList = Object.SupModuleList + AddToLibraryClassSection(SectionEBCDict, SupModuleList, Item) + + Section = "" + for ModuleType in ModuleTypes: + SectionCommonModule = "\n".join(SectionCommonDict.get(ModuleType, [])) + if SectionCommonModule != "": + Section += "[%s.Common.%s]\n%s\n" % (SectionName, ModuleType, SectionCommonModule) + Section += "\n" + for ModuleType in ModuleTypes: + ListIA32 = SectionIA32Dict.get(ModuleType, []) + if ListIA32 != []: + SectionIA32Module = "\n".join(SectionIA32Dict.get(ModuleType, [])) + if SectionIA32Module != "": + Section += "[%s.IA32.%s]\n%s\n" % (SectionName, ModuleType, SectionIA32Module) + Section += "\n" + ListX64 = SectionX64Dict.get(ModuleType, []) + if ListX64 != []: + SectionX64Module = "\n".join(SectionX64Dict.get(ModuleType, [])) + if SectionX64Module != "": + Section += "[%s.X64.%s]\n%s\n" % (SectionName, ModuleType, SectionX64Module) + Section += "\n" + ListIPF = SectionIPFDict.get(ModuleType, []) + if ListIPF != []: + SectionIPFModule = "\n".join(SectionIPFDict.get(ModuleType, [])) + if SectionIPFModule != "": + Section += "[%s.IPF.%s]\n%s\n" % (SectionName, ModuleType, SectionIPFModule) + Section += "\n" + ListEBC = SectionEBCDict.get(ModuleType, []) + if ListEBC != []: + SectionEBCModule = "\n".join(SectionEBCDict.get(ModuleType, [])) + if SectionEBCModule != "": + Section += "[%s.EBC.%s]\n%s\n" % (SectionName, ModuleType, SectionEBCModule) + Section += "\n" + + if Section != "": + Section += "\n" + return Section + +## Store Library Classes section +# +# Write [LibraryClasses] section to the DscFile based on Platform class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param DscFile The output DSC file to store the Library Classes section +# @param Platform An input Platform class object +# +def StorePlatformLibraryClassesSection(DscFile, Platform): + Section = GetLibraryClassesSection("LibraryClasses", GetPlatformLibraryClassItem, Platform.LibraryClasses.LibraryList) + List = [] + List.append("################################################################################") + List.append("#") + List.append("# Library Class section - list of all Library Classes needed by this Platform.") + List.append("#") + List.append("################################################################################") + SectionHeader = "\n".join(List) + SectionHeader += "\n" + Section = SectionHeader + Section + StoreTextFile(DscFile, Section) + +## Store Pcd section +# +# Write [Pcd] section to the DscFile based on Platform class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param DscFile The output DSC file to store the Build Options section +# @param Platform An input Platform class object +# +def StorePlatformPcdSection(DscFile, Platform): + # {PcdsFixedAtBuild:String1, PcdsFixedAtBuild:String2, PcdsPatchableInModule:String3} + SectionDict = {} + # + # [PcdsFixedAtBuild], [PcdsPatchableInModule] and [PcdsFeatureFlag] are from platform.modules + # [PcdsDynamic] is from platform.DynamicPcdBuildDefinitions + # + Modules = Platform.Modules.ModuleList # it's a list of modules + for Module in Modules: + PcdBuildDefinitions = Module.PcdBuildDefinitions # it's a list of PcdData + for PcdData in PcdBuildDefinitions: + if PcdData.ItemType == "FEATURE_FLAG": + List = [] + List.append(PcdData.TokenSpaceGuidCName + "." + PcdData.C_NAME) + List.append(PcdData.Value) + String = "|".join(List) + ItemType = PcdData.ItemType + SectionPcdsFeatureFlag = SectionDict.get(ItemType, []) + if String not in SectionPcdsFeatureFlag: + SectionPcdsFeatureFlag.append(String) + SectionDict[ItemType] = SectionPcdsFeatureFlag + else: + List = [] + List.append(PcdData.TokenSpaceGuidCName + "." + PcdData.C_NAME) + List.append(PcdData.Value) + List.append(PcdData.Token) + List.append(PcdData.DatumType) + List.append(PcdData.MaxDatumSize) + String = "|".join(List) + ItemType = PcdData.ItemType + if PcdData.ItemType == "FIXED_AT_BUILD": + SectionPcdsFixedAtBuild = SectionDict.get(ItemType, []) + if String not in SectionPcdsFixedAtBuild: + SectionPcdsFixedAtBuild.append(String) + SectionDict[ItemType] = SectionPcdsFixedAtBuild + #elif PcdData.ItemType == "FEATURE_FLAG": + #SectionPcdsFeatureFlag = SectionDict.get(ItemType, []) + #if String not in SectionPcdsFeatureFlag: + #SectionPcdsFeatureFlag.append(String) + #SectionDict[ItemType] = SectionPcdsFeatureFlag + elif PcdData.ItemType == "PATCHABLE_IN_MODULE": + SectionPcdsPatchableInModule = SectionDict.get(ItemType, []) + if String not in SectionPcdsPatchableInModule: + SectionPcdsPatchableInModule.append(String) + SectionDict[ItemType] = SectionPcdsPatchableInModule + elif PcdData.ItemType == "DYNAMIC": + SectionPcdsDynamic = SectionDict.get(ItemType, []) + if String not in SectionPcdsDynamic: + SectionPcdsDynamic.append(String) + SectionDict[ItemType] = SectionPcdsDynamic + + DynamicPcdBuildDefinitions = Platform.DynamicPcdBuildDefinitions # It's a list + for PcdBuildData in DynamicPcdBuildDefinitions: + List = [] + List.append(PcdData.TokenSpaceGuidCName + "." + PcdData.C_NAME) + List.append(PcdData.Token) + List.append(PcdData.DatumType) + List.append(PcdData.MaxDatumSize) + String = "|".join(List) + if PcdBuildData.ItemType == "DYNAMIC": + ItemType = PcdBuildData.ItemType + SectionPcdsDynamic = SectionDict.get(ItemType, []) + if String not in SectionPcdsDynamic: + SectionPcdsDynamic.append(String) + SectionDict[ItemType] = SectionPcdsDynamic + ItemType = "FIXED_AT_BUILD" + Section = "[PcdsFixedAtBuild]\n " + "\n ".join(SectionDict.get(ItemType, [])) + ItemType = "FEATURE_FLAG" + Section += "\n\n[PcdsFeatureFlag]\n " + "\n ".join(SectionDict.get(ItemType, [])) + ItemType = "PATCHABLE_IN_MODULE" + Section += "\n\n[PcdsPatchableInModule]\n " + "\n ".join(SectionDict.get(ItemType, [])) + Section += "\n\n" + List = [] + List.append("################################################################################") + List.append("#") + List.append("# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform.") + List.append("#") + List.append("################################################################################") + String = "\n".join(List) + Section += String + ItemType = "DYNAMIC" + Section += "\n\n[PcdsDynamic]\n " + "\n ".join(SectionDict.get(ItemType, [])) + Section += "\n\n" + + List = [] + List.append("################################################################################") + List.append("#") + List.append("# Pcd Section - list of all EDK II PCD Entries defined by this Platform.") + List.append("#") + List.append("################################################################################") + SectionHeader = "\n".join(List) + SectionHeader += "\n" + Section = SectionHeader + Section + StoreTextFile(DscFile, Section) + +## Add item to a section +# +# Add an Item with specific CPU architecture to section dictionary. +# The possible duplication is ensured to be removed. +# +# @param Section Section dictionary indexed by CPU architecture +# @param Arch CPU architecture: Ia32, X64, Ipf, Ebc or Common +# @param Item The Item to be added to section dictionary +# +def AddToSection(Section, Arch, Item): + SectionArch = Section.get(Arch, []) + if Item not in SectionArch: + SectionArch.append(Item) + Section[Arch] = SectionArch + +## Get section contents +# +# Return the content of section named SectionName. +# the contents is based on Methods and ObjectLists. +# +# @param SectionName The name of the section +# @param Method A function returning a string item of an object +# @param ObjectList The list of object +# +# @retval Section The string content of a section +# +def GetSection(SectionName, Method, ObjectList): + SupportedArches = ["COMMON", "IA32", "X64", "IPF", "EBC"] + SectionDict = {} + for Object in ObjectList: + if Object.FilePath == "": + continue + Item = Method(Object) + if Item == "": + continue + Item = " %s" % Item + Arches = Object.SupArchList + if len(Arches) == 4: + AddToSection(SectionDict, "common", Item) + else: + for Arch in SupportedArches: + if Arch.upper() in Arches: + AddToSection(SectionDict, Arch, Item) + + Section = "" + for Arch in SupportedArches: + SectionArch = "\n".join(SectionDict.get(Arch, [])) + if SectionArch != "": + Section += "[%s.%s]\n%s\n" % (SectionName, Arch, SectionArch) + Section += "\n" + if Section != "": + Section += "\n" + return Section + +## Return a Platform Component Item +# +# Read the input Platform Component object and return one line of Platform Component Item. +# +# @param Component An input Platform Component class object +# +# @retval ComponentItem A Platform Component Item +# +def GetPlatformComponentItem(Component): + List = [] + Section = {} + + List.append("$(WORKSPACE)/" + Component.FilePath) + + LibraryClasses = Component.LibraryClasses + if LibraryClasses != []: + List = [] + List.append("$(WORKSPACE)/" + Component.FilePath + " {") + List.append("") + for LibraryClass in LibraryClasses: + if LibraryClass == ["", ""]: + continue + List.append(" " + LibraryClass[0] + "|$(WORKSPACE)/" + LibraryClass[1]) + + PcdBuildDefinitions = Component.PcdBuildDefinitions + for PcdData in PcdBuildDefinitions: + if PcdData.ItemType == "FEATURE_FLAG": + List1 = [] + List1.append(PcdData.TokenSpaceGuidCName + "." + PcdData.C_NAME) + List1.append(PcdData.Value) + String = "|".join(List1) + ItemType = PcdData.ItemType + SectionPcd = Section.get(ItemType, []) + if String not in SectionPcd: + SectionPcd.append(String) + Section[ItemType] = SectionPcd + else: + List1 = [] + List1.append(PcdData.TokenSpaceGuidCName + "." + PcdData.C_NAME) + List1.append(PcdData.Value) + List1.append(PcdData.Token) + List1.append(PcdData.DatumType) + List1.append(PcdData.MaxDatumSize) + String = "|".join(List1) + ItemType = PcdData.ItemType + if ItemType == "FIXED_AT_BUILD": + SectionPcd = Section.get(ItemType, []) + if String not in SectionPcd: + SectionPcd.append(String) + Section[ItemType] = SectionPcd + #elif ItemType == "FEATURE_FLAG": + #SectionPcd = Section.get(ItemType, []) + #if String not in SectionPcd: + #SectionPcd.append(String) + #Section[ItemType] = SectionPcd + elif ItemType == "PATCHABLE_IN_MODULE": + SectionPcd = Section.get(ItemType, []) + if String not in SectionPcd: + SectionPcd.append(String) + Section[ItemType] = SectionPcd + elif ItemType == "DYNAMIC": + SectionPcd = Section.get(ItemType, []) + if String not in SectionPcd: + SectionPcd.append(String) + Section[ItemType] = SectionPcd + + ItemType = "FIXED_AT_BUILD" + if Section.get(ItemType, []) != []: + List.append("") + List.append(" " + "\n ".join(Section.get(ItemType,[]))) + ItemType = "FEATURE_FLAG" + if Section.get(ItemType, []) != []: + List.append("") + List.append(" " + "\n ".join(Section.get(ItemType,[]))) + ItemType = "PATCHABLE_IN_MODULE" + if Section.get(ItemType, []) != []: + List.append("") + List.append(" " + "\n ".join(Section.get(ItemType,[]))) + ItemType = "DYNAMIC" + if Section.get(ItemType, []) != []: + List.append("") + List.append(" " + "\n ".join(Section.get(ItemType,[]))) + + ListOption = [] + SectionOption = "" + ListBuildOptions = Component.BuildOptions # a list + if ListBuildOptions != []: + SectionOption += "\n \n" + for BuildOptions in ListBuildOptions: + Options = BuildOptions.Options + for Option in Options: + for Item in Option.BuildTargetList: + ListOption.append(Item) + List.append(Option.ToolChainFamily) + for Item in Option.SupArchList: + ListOption.append(Item) + ListOption.append(Option.ToolCode) + ListOption.append("FLAGS") + #print ListOption + SectionOption += " " + "_".join(List) + " = " + Option.Option + "\n" + ListOption = [] + if SectionOption != "": + List.append(SectionOption) + if List != ["$(WORKSPACE)/" + Component.FilePath]: + List.append("}\n") + + return "\n ".join(List) + +## Store Components section. +# +# Write [Components] section to the DscFile based on Platform class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param DscFile The output DSC file to store the Components section +# @param Platform An input Platform class object +# +def StorePlatformComponentsSection(DscFile, Platform): + Section = GetSection("Components", GetPlatformComponentItem, Platform.Modules.ModuleList) + List = [] + List.append("################################################################################") + List.append("#") + List.append("# Components Section - list of all EDK II Modules needed by this Platform.") + List.append("#") + List.append("################################################################################") + SectionHeader = "\n".join(List) + SectionHeader += "\n" + Section = SectionHeader + Section + StoreTextFile(DscFile, Section) + +## Store User Extensions section. +# +# Write [UserExtensions] section to the InfFile based on Module class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param DscFile The output DSC file to store the User Extensions section +# @param Platform An input Platform class object +# +def StorePlatformUserExtensionsSection(DscFile, Platform): + Section = "".join(map(GetUserExtensions, Platform.UserExtensions)) + List = [] + List.append("################################################################################") + List.append("#") + List.append("# User Extensions Section - list of all User Extensions specified by user.") + List.append("#") + List.append("################################################################################") + SectionHeader = "\n".join(List) + SectionHeader += "\n" + Section = SectionHeader + Section + StoreTextFile(DscFile, Section) + +## Store a Platform class object to a new DSC file. +# +# Read an input Platform class object and save the contents to a new DSC file. +# +# @param DSCFileName The output DSC file +# @param Platform An input Platform class object +# +def StoreDsc(DscFileName, Platform): + DscFile = open(DscFileName, "w+") + EdkLogger.info("Save file to %s" % DscFileName) + + StoreHeader(DscFile, Platform.Header) + StorePlatformDefinesSection(DscFile, Platform) + StorePlatformBuildOptionsSection(DscFile,Platform) + StorePlatformSkuIdsSection(DscFile,Platform) + StorePlatformLibrariesSection(DscFile,Platform) # new in dsc, Edk I components, list of INF files + StorePlatformLibraryClassesSection(DscFile, Platform) # LibraryClasses are from Modules + StorePlatformPcdSection(DscFile, Platform) + #StorePlatformPcdDynamicSection(DscFile, Platform) + StorePlatformComponentsSection(DscFile,Platform) + StorePlatformUserExtensionsSection(DscFile,Platform) + DscFile.close() + +if __name__ == '__main__': + pass diff --git a/BaseTools/Source/Python/fpd2dsc/__init__.py b/BaseTools/Source/Python/fpd2dsc/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/BaseTools/Source/Python/fpd2dsc/fpd2dsc.py b/BaseTools/Source/Python/fpd2dsc/fpd2dsc.py new file mode 100644 index 0000000000..a22ff5a685 --- /dev/null +++ b/BaseTools/Source/Python/fpd2dsc/fpd2dsc.py @@ -0,0 +1,116 @@ +## @file +# Convert an XML-based FPD file to a text-based DSC file. +# +# Copyright (c) 2007, 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 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, re, sys, xml.dom.minidom #XmlRoutines, EdkIIWorkspace +from LoadFpd import LoadFpd +from StoreDsc import StoreDsc +from optparse import OptionParser + +# Version and Copyright +__version_number__ = "1.0" +__version__ = "%prog Version " + __version_number__ +__copyright__ = "Copyright (c) 2007, Intel Corporation All rights reserved." + +## Parse command line options +# +# Using standard Python module optparse to parse command line option of this tool. +# +# @retval Options A optparse.Values object containing the parsed options +# @retval Args All the arguments got from the command line +# +def MyOptionParser(): + """ Argument Parser """ + usage = "%prog [options] input_filename" + parser = OptionParser(usage=usage,description=__copyright__,version="%prog " + str(__version_number__)) + parser.add_option("-o", "--output", dest="outfile", help="Specific Name of the DSC file to create, otherwise it is the FPD filename with the extension repalced.") + parser.add_option("-a", "--auto", action="store_true", dest="autowrite", default=False, help="Automatically create output files and write the DSC file") + parser.add_option("-q", "--quiet", action="store_const", const=0, dest="verbose", help="Do not print any messages, just return either 0 for succes or 1 for failure") + parser.add_option("-v", "--verbose", action="count", dest="verbose", help="Do not print any messages, just return either 0 for succes or 1 for failure") + parser.add_option("-d", "--debug", action="store_true", dest="debug", default=False, help="Enable printing of debug messages.") + parser.add_option("-w", "--workspace", dest="workspace", default=str(os.environ.get('WORKSPACE')), help="Specify workspace directory.") + (options, args) = parser.parse_args(sys.argv[1:]) + + return options,args + +## 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(): + global Options + global Args + global WorkSpace + Options,Args = MyOptionParser() + + WorkSpace = "" + #print Options.workspace + if (Options.workspace == None): + print "ERROR: E0000: WORKSPACE not defined.\n Please set the WORKSPACE environment variable to the location of the EDK II install directory." + sys.exit(1) + else: + WorkSpace = Options.workspace + if (Options.debug): + print "Using Workspace:", WorkSpace + try: + Options.verbose +=1 + except: + Options.verbose = 1 + pass + + InputFile = "" + if Args == []: + print "usage:" "%prog [options] input_filename" + else: + InputFile = Args[0] + #print InputFile + if InputFile != "": + FileName = InputFile + if ((Options.verbose > 1) | (Options.autowrite)): + print "FileName:",InputFile + else: + print "ERROR: E0001 - You must specify an input filename" + sys.exit(1) + + if (Options.outfile): + OutputFile = Options.outfile + else: + OutputFile = FileName.replace('.fpd', '.dsc') + + if ((Options.verbose > 2) or (Options.debug)): + print "Output Filename:", OutputFile + + try: + Platform = LoadFpd(FileName) + StoreDsc(OutputFile, Platform) + return 0 + except Exception, e: + print e + return 1 + +if __name__ == '__main__': + sys.exit(Main()) + #pass + #global Options + #global Args + #Options,Args = MyOptionParser() + + #Main() + #sys.exit(0) \ No newline at end of file diff --git a/BaseTools/Source/Python/msa2inf/ConvertModule.py b/BaseTools/Source/Python/msa2inf/ConvertModule.py new file mode 100644 index 0000000000..e0d7b88695 --- /dev/null +++ b/BaseTools/Source/Python/msa2inf/ConvertModule.py @@ -0,0 +1,112 @@ +## @file +# Convert an MSA Module class object ot an INF Module class object by filling +# several info required by INF file. +# +# Copyright (c) 2007, 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 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 +# +from LoadMsa import LoadMsa +from StoreInf import StoreInf +from Common.MigrationUtilities import * +from EdkIIWorkspaceGuidsInfo import gEdkIIWorkspaceGuidsInfo + +#The default INF version number tool generates. +gInfVersion = "0x00010005" + +## Add required version information. +# +# Add the default INF version, EFI specificiation version and EDK release +# version to Module class object. +# +# @param Module An input Module class object. +# +def AddModuleMiscVersion(Module): + Version = gInfVersion + Module.Header.InfVersion = Version + + Version = Module.Header.Specification.get("EFI_SPECIFICATION_VERSION", "") + Module.Header.EfiSpecificationVersion = Version + + Version = Module.Header.Specification.get("EDK_RELEASE_VERSION", "") + Module.Header.EdkReleaseVersion = Version + + +## Add Module produced library class. +# +# Add the produced library class from library class list whose usage type is +# always produced. +# +# @param Module An input Module class object. +# +def AddModuleProducedLibraryClass(Module): + for LibraryClass in Module.LibraryClasses: + if "ALWAYS_PRODUCED" in LibraryClass.Usage: + Module.Header.LibraryClass.append(LibraryClass) + + +## Add Module Package Dependency path. +# +# Translate Package Dependency Guid to a file path relative to workspace. +# +# @param Module An input Module class object. +# +def AddModulePackageDependencyPath(Module): + for PackageDependency in Module.PackageDependencies: + PackageGuid = PackageDependency.PackageGuid + PackageVersion = PackageDependency.PackageVersion + + GuidToFilePath = gEdkIIWorkspaceGuidsInfo.ResolvePackageFilePath + PackageFilePath = GuidToFilePath(PackageGuid, PackageVersion) + PackageDependency.FilePath = PackageFilePath + + +## Add Module Recommended Library Instance path. +# +# Translate Module Recommened Library Instance Guid to a file path relative to +# workspace. +# +# @param Module An input Module class object. +# +def AddModuleRecommonedLibraryInstancePath(Module): + for LibraryClass in Module.LibraryClasses: + if "ALWAYS_PRODUCED" in LibraryClass.Usage: + continue + + if LibraryClass.RecommendedInstanceGuid == "": + continue + + LibraryGuid = LibraryClass.RecommendedInstanceGuid + LibraryVersion = LibraryClass.RecommendedIntanceVersion + + GuidToFilePath = gEdkIIWorkspaceGuidsInfo.ResolveModuleFilePath + LibraryInstance = GuidToFilePath(LibraryGuid, LibraryVersion) + LibraryClass.RecommendedIntance = LibraryInstance + + +## Convert MSA Module class object to INF Module class object. +# +# Convert MSA module class ojbect to INF Module class object by filling in +# several information required by INF file. +# +# @param Module An input Module class object. +# +def ConvertMsaModuleToInfModule(Module): + AddModuleMiscVersion(Module) + AddModuleProducedLibraryClass(Module) + AddModulePackageDependencyPath(Module) + AddModuleRecommonedLibraryInstancePath(Module) + + +if __name__ == '__main__': + pass + \ No newline at end of file diff --git a/BaseTools/Source/Python/msa2inf/EdkIIWorkspaceGuidsInfo.py b/BaseTools/Source/Python/msa2inf/EdkIIWorkspaceGuidsInfo.py new file mode 100644 index 0000000000..f1c8d60d75 --- /dev/null +++ b/BaseTools/Source/Python/msa2inf/EdkIIWorkspaceGuidsInfo.py @@ -0,0 +1,325 @@ +## @file +# Collects the Guid Information in current workspace. +# +# Copyright (c) 2007, 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 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 fnmatch +from Common.EdkIIWorkspace import EdkIIWorkspace +from Common.MigrationUtilities import * + +## A class for EdkII work space to resolve Guids. +# +# This class inherits from EdkIIWorkspace and collects the Guids information +# in current workspace. The Guids information is important to translate the +# package Guids and recommended library instances Guids to relative file path +# (to workspace directory) in MSA files. +# +class EdkIIWorkspaceGuidsInfo(EdkIIWorkspace): + + ## The classconstructor. + # + # The constructor initialize workspace directory. It does not collect + # pakage and module Guids info at initialization; instead, it collects them + # on the fly. + # + # @param self The object pointer. + # + def __init__(self): + # Initialize parent class. + EdkIIWorkspace.__init__(self) + # The internal map from Guid to FilePath. + self.__GuidToFilePath = {} + # The internal package directory list. + self.__PackageDirList = [] + # The internal flag to indicate whether package Guids info has been + # to avoid re-collection collected. + self.__PackageGuidInitialized = False + # The internal flag to indicate whether module Guids info has been + # to avoid re-collection collected. + self.__ModuleGuidInitialized = False + + ## Add Guid, Version and FilePath to Guids database. + # + # Add Guid, Version and FilePath to Guids database. It constructs a map + # table from Guid, Version to FilePath internally. If also detects possible + # Guid collision. For now, the version information is simply ignored and + # Guid value itself acts as master key. + # + # @param self The object pointer. + # @param Guid The Guid Value. + # @param Version The version information + # + # @retval True The Guid value is successfully added to map table. + # @retval False The Guid is an empty string or the map table + # already contains a same Guid. + # + def __AddGuidToFilePath(self, Guid, Version, FilePath): + if Guid == "": + EdkLogger.info("Cannot find Guid in file %s" % FilePath) + return False + #Add the Guid value to map table to ensure case insensitive comparison. + OldFilePath = self.__GuidToFilePath.setdefault(Guid.lower(), FilePath) + if OldFilePath == FilePath: + EdkLogger.verbose("File %s has new Guid '%s'" % (FilePath, Guid)) + return True + else: + EdkLogger.info("File %s has duplicate Guid with & %s" % (FilePath, OldFilePath)) + return False + + + ## Gets file information from a module description file. + # + # Extracts Module Name, File Guid and Version number from INF, MSA and NMSA + # file. It supports to exact such information from text based INF file or + # XML based (N)MSA file. + # + # @param self The object pointer. + # @param FileName The input module file name. + # + # @retval True This module file represents a new module discovered + # in current workspace. + # @retval False This module file is not regarded as a valid module. + # The File Guid cannot be extracted or the another + # file with the same Guid already exists + # + def __GetModuleFileInfo(self, FileName): + if fnmatch.fnmatch(FileName, "*.inf"): + TagTuple = ("BASE_NAME", "FILE_GUID", "VERSION_STRING") + (Name, Guid, Version) = GetTextFileInfo(FileName, TagTuple) + else : + XmlTag1 = "ModuleSurfaceArea/MsaHeader/ModuleName" + XmlTag2 = "ModuleSurfaceArea/MsaHeader/GuidValue" + XmlTag3 = "ModuleSurfaceArea/MsaHeader/Version" + TagTuple = (XmlTag1, XmlTag2, XmlTag3) + (Name, Guid, Version) = GetXmlFileInfo(FileName, TagTuple) + + return self.__AddGuidToFilePath(Guid, Version, FileName) + + + ## Gets file information from a package description file. + # + # Extracts Package Name, File Guid and Version number from INF, SPD and NSPD + # file. It supports to exact such information from text based DEC file or + # XML based (N)SPD file. EDK Compatibility Package is hardcoded to be + # ignored since no EDKII INF file depends on that package. + # + # @param self The object pointer. + # @param FileName The input package file name. + # + # @retval True This package file represents a new package + # discovered in current workspace. + # @retval False This package is not regarded as a valid package. + # The File Guid cannot be extracted or the another + # file with the same Guid already exists + # + def __GetPackageFileInfo(self, FileName): + if fnmatch.fnmatch(FileName, "*.dec"): + TagTuple = ("PACKAGE_NAME", "PACKAGE_GUID", "PACKAGE_VERSION") + (Name, Guid, Version) = GetTextFileInfo(FileName, TagTuple) + else: + XmlTag1 = "PackageSurfaceArea/SpdHeader/PackageName" + XmlTag2 = "PackageSurfaceArea/SpdHeader/GuidValue" + XmlTag3 = "PackageSurfaceArea/SpdHeader/Version" + TagTuple = (XmlTag1, XmlTag2, XmlTag3) + (Name, Guid, Version) = GetXmlFileInfo(FileName, TagTuple) + + if Name == "EdkCompatibilityPkg": + # Do not scan EDK compatibitilty package to avoid Guid collision + # with those in EDK Glue Library. + EdkLogger.verbose("Bypass EDK Compatibility Pkg") + return False + + return self.__AddGuidToFilePath(Guid, Version, FileName) + + ## Iterate on all package files listed in framework database file. + # + # Yields all package description files listed in framework database files. + # The framework database file describes the packages current workspace + # includes. + # + # @param self The object pointer. + # + def __FrameworkDatabasePackageFiles(self): + XmlFrameworkDb = XmlParseFile(self.WorkspaceFile) + XmlTag = "FrameworkDatabase/PackageList/Filename" + for PackageFile in XmlElementList(XmlFrameworkDb, XmlTag): + yield os.path.join(self.WorkspaceDir, PackageFile) + + + ## Iterate on all package files in current workspace directory. + # + # Yields all package description files listed in current workspace + # directory. This happens when no framework database file exists. + # + # @param self The object pointer. + # + def __TraverseAllPackageFiles(self): + for Path, Dirs, Files in os.walk(self.WorkspaceDir): + # Ignore svn version control directory. + if ".svn" in Dirs: + Dirs.remove(".svn") + if "Build" in Dirs: + Dirs.remove("Build") + # Assume priority from high to low: DEC, NSPD, SPD. + PackageFiles = fnmatch.filter(Files, "*.dec") + if len(PackageFiles) == 0: + PackageFiles = fnmatch.filter(Files, "*.nspd") + if len(PackageFiles) == 0: + PackageFiles = fnmatch.filter(Files, "*.spd") + + for File in PackageFiles: + # Assume no more package decription file in sub-directory. + del Dirs[:] + yield os.path.join(Path, File) + + ## Iterate on all module files in current package directory. + # + # Yields all module description files listed in current package + # directory. + # + # @param self The object pointer. + # + def __TraverseAllModuleFiles(self): + for PackageDir in self.__PackageDirList: + for Path, Dirs, Files in os.walk(PackageDir): + # Ignore svn version control directory. + if ".svn" in Dirs: + Dirs.remove(".svn") + # Assume priority from high to low: INF, NMSA, MSA. + ModuleFiles = fnmatch.filter(Files, "*.inf") + if len(ModuleFiles) == 0: + ModuleFiles = fnmatch.filter(Files, "*.nmsa") + if len(ModuleFiles) == 0: + ModuleFiles = fnmatch.filter(Files, "*.msa") + + for File in ModuleFiles: + yield os.path.join(Path, File) + + ## Initialize package Guids info mapping table. + # + # Collects all package guids map to package decription file path. This + # function is invokes on demand to avoid unnecessary directory scan. + # + # @param self The object pointer. + # + def __InitializePackageGuidInfo(self): + if self.__PackageGuidInitialized: + return + + EdkLogger.verbose("Start to collect Package Guids Info.") + + WorkspaceFile = os.path.join("Conf", "FrameworkDatabase.db") + self.WorkspaceFile = os.path.join(self.WorkspaceDir, WorkspaceFile) + + # Try to find the frameworkdatabase file to discover package lists + if os.path.exists(self.WorkspaceFile): + TraversePackage = self.__FrameworkDatabasePackageFiles + EdkLogger.verbose("Package list bases on: %s" % self.WorkspaceFile) + else: + TraversePackage = self.__TraverseAllPackageFiles + EdkLogger.verbose("Package list in: %s" % self.WorkspaceDir) + + for FileName in TraversePackage(): + if self.__GetPackageFileInfo(FileName): + PackageDir = os.path.dirname(FileName) + EdkLogger.verbose("Find new package directory %s" % PackageDir) + self.__PackageDirList.append(PackageDir) + + self.__PackageGuidInitialized = True + + ## Initialize module Guids info mapping table. + # + # Collects all module guids map to module decription file path. This + # function is invokes on demand to avoid unnecessary directory scan. + # + # @param self The object pointer. + # + def __InitializeModuleGuidInfo(self): + if self.__ModuleGuidInitialized: + return + EdkLogger.verbose("Start to collect Module Guids Info") + + self.__InitializePackageGuidInfo() + for FileName in self.__TraverseAllModuleFiles(): + if self.__GetModuleFileInfo(FileName): + EdkLogger.verbose("Find new module %s" % FileName) + + self.__ModuleGuidInitialized = True + + ## Get Package file path by Package guid and Version. + # + # Translates the Package Guid and Version to a file path relative + # to workspace directory. If no package in current workspace match the + # input Guid, an empty file path is returned. For now, the version + # value is simply ignored. + # + # @param self The object pointer. + # @param Guid The Package Guid value to look for. + # @param Version The Package Version value to look for. + # + def ResolvePackageFilePath(self, Guid, Version = ""): + self.__InitializePackageGuidInfo() + + EdkLogger.verbose("Resolve Package Guid '%s'" % Guid) + FileName = self.__GuidToFilePath.get(Guid.lower(), "") + if FileName == "": + EdkLogger.info("Cannot resolve Package Guid '%s'" % Guid) + else: + FileName = self.WorkspaceRelativePath(FileName) + FileName = os.path.splitext(FileName)[0] + ".dec" + FileName = FileName.replace("\\", "/") + return FileName + + ## Get Module file path by Package guid and Version. + # + # Translates the Module Guid and Version to a file path relative + # to workspace directory. If no module in current workspace match the + # input Guid, an empty file path is returned. For now, the version + # value is simply ignored. + # + # @param self The object pointer. + # @param Guid The Module Guid value to look for. + # @param Version The Module Version value to look for. + # + def ResolveModuleFilePath(self, Guid, Version = ""): + self.__InitializeModuleGuidInfo() + + EdkLogger.verbose("Resolve Module Guid '%s'" % Guid) + FileName = self.__GuidToFilePath.get(Guid.lower(), "") + if FileName == "": + EdkLogger.info("Cannot resolve Module Guid '%s'" % Guid) + else: + FileName = self.WorkspaceRelativePath(FileName) + FileName = os.path.splitext(FileName)[0] + ".inf" + FileName = FileName.replace("\\", "/") + return FileName + +# A global class object of EdkIIWorkspaceGuidsInfo for external reference. +gEdkIIWorkspaceGuidsInfo = EdkIIWorkspaceGuidsInfo() + +# This acts like the main() function for the script, unless it is 'import'ed +# into another script. +if __name__ == '__main__': + # Test the translation of package Guid. + MdePkgGuid = "1E73767F-8F52-4603-AEB4-F29B510B6766" + OldMdePkgGuid = "5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec" + print gEdkIIWorkspaceGuidsInfo.ResolveModuleFilePath(MdePkgGuid) + print gEdkIIWorkspaceGuidsInfo.ResolveModuleFilePath(OldMdePkgGuid) + + # Test the translation of module Guid. + UefiLibGuid = "3a004ba5-efe0-4a61-9f1a-267a46ae5ba9" + UefiDriverModelLibGuid = "52af22ae-9901-4484-8cdc-622dd5838b09" + print gEdkIIWorkspaceGuidsInfo.ResolveModuleFilePath(UefiLibGuid) + print gEdkIIWorkspaceGuidsInfo.ResolveModuleFilePath(UefiDriverModelLibGuid) diff --git a/BaseTools/Source/Python/msa2inf/LoadMsa.py b/BaseTools/Source/Python/msa2inf/LoadMsa.py new file mode 100644 index 0000000000..4995f2cd0c --- /dev/null +++ b/BaseTools/Source/Python/msa2inf/LoadMsa.py @@ -0,0 +1,747 @@ +## @file +# Open an MSA file and load all its contents to a ModuleClass object. +# +# Copyright (c) 2007, 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 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 +from CommonDataClass.ModuleClass import * +from Common.XmlRoutines import * +from Common.MigrationUtilities import * + + +## Load a list of Module Cloned Records. +# +# Read an input Module XML DOM object and return a list of Cloned Records +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# +# @retvel ClonedRecords A list of Cloned Records loaded from XmlMsa. +# +def LoadModuleClonedRecords(XmlMsa): + XmlTag = "ModuleSurfaceArea/ModuleDefinitions/ClonedFrom/Cloned" + return map(LoadClonedRecord, XmlList(XmlMsa, XmlTag)) + +## Load Module Header. +# +# Read an input Module XML DOM object and return Module Header class object +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# @param MsaFileName The file path of MSA File. +# +# @retvel ModuleHeader A new Module Header object loaded from XmlMsa. +# +def LoadModuleHeader(XmlMsa, MsaFileName): + ModuleHeader = ModuleHeaderClass() + + XmlTag = "ModuleSurfaceArea/MsaHeader" + MsaHeader = XmlNode(XmlMsa, XmlTag) + + SetIdentification(ModuleHeader, MsaHeader, "ModuleName", MsaFileName) + SetCommonHeader(ModuleHeader, MsaHeader) + + XmlTag = "ModuleSurfaceArea/ModuleDefinitions/SupportedArchitectures" + ModuleHeader.SupArchList = XmlElement(XmlMsa, XmlTag).split() + + XmlTag = "ModuleSurfaceArea/ModuleDefinitions/BinaryModule" + if XmlElement(XmlMsa, XmlTag).lower() == "true": + ModuleHeader.BinaryModule = True + + XmlTag = "ModuleSurfaceArea/ModuleDefinitions/OutputFileBasename" + ModuleHeader.OutputFileBasename = XmlElement(XmlMsa, XmlTag) + + XmlTag = "ModuleSurfaceArea/ModuleDefinitions/ClonedForm" + ModuleHeader.ClonedFrom = LoadModuleClonedRecords(XmlMsa) + + XmlTag = "ModuleSurfaceArea/Externs/PcdDriverTypes" + ModuleHeader.PcdIsDriver = XmlElement(XmlMsa, XmlTag) + + XmlTag = "ModuleSurfaceArea/Externs/TianoR8FlashMap_h" + if XmlElement(XmlMsa, XmlTag).lower() == "true": + ModuleHeader.TianoR8FlashMap_h = True + + XmlTag = "ModuleSurfaceArea/Externs/Specification" + for Specification in XmlElementList(XmlMsa, XmlTag): + AddToSpecificationDict(ModuleHeader.Specification, Specification) + + return ModuleHeader + + +## Load a list of Module Library Classes. +# +# Read an input Module XML DOM object and return a list of Library Classes +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# +# @retvel LibraryClasses A list of Library Classes loaded from XmlMsa. +# +def LoadModuleLibraryClasses(XmlMsa): + XmlTag = "ModuleSurfaceArea/LibraryClassDefinitions/LibraryClass" + return map(LoadLibraryClass, XmlList(XmlMsa, XmlTag)) + + +## Load a new Module Source class object. +# +# Read an input XML Source DOM object and return an object of Source +# contained in the DOM object. +# +# @param XmlFilename A child XML DOM object in Module XML DOM. +# +# @retvel ModuleSource A new Source object created by XmlFilename. +# +def LoadModuleSource(XmlFilename): + ModuleSource = ModuleSourceFileClass() + + ModuleSource.SourceFile = XmlElementData(XmlFilename) + + XmlTag = "TagName" + ModuleSource.TagName = XmlAttribute(XmlFilename, XmlTag) + + XmlTag = "ToolCode" + ModuleSource.ToolCode = XmlAttribute(XmlFilename, XmlTag) + + XmlTag = "ToolChainFamily" + ModuleSource.ToolChainFamily = XmlAttribute(XmlFilename, XmlTag) + + SetCommon(ModuleSource, XmlFilename) + + return ModuleSource + + +## Load a list of Module Sources. +# +# Read an input Module XML DOM object and return a list of Sources +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# +# @retvel Sources A list of Sources loaded from XmlMsa. +# +def LoadModuleSources(XmlMsa): + XmlTag = "ModuleSurfaceArea/SourceFiles/Filename" + return map(LoadModuleSource, XmlList(XmlMsa, XmlTag)) + + +## Load a new Module Binary class object. +# +# Read an input XML Binary DOM object and return an object of Binary +# contained in the DOM object. +# +# @param XmlFilename A child XML DOM object in Module XML DOM. +# +# @retvel ModuleBinary A new Binary object created by XmlFilename. +# +def LoadModuleBinary(XmlFilename): + ModuleBinary = ModuleBinaryFileClass() + + ModuleBinary.BinaryFile = XmlElementData(XmlFilename) + + XmlTag = "FileType" + ModuleBinary.FileType = XmlElementAttribute(XmlFilename, XmlTag) + + SetCommon(ModuleBinary, XmlFilename) + + +## Load a list of Module Binaries. +# +# Read an input Module XML DOM object and return a list of Binaries +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# +# @retvel Binaries A list of Binaries loaded from XmlMsa. +# +def LoadModuleBinaries(XmlMsa): + XmlTag = "ModuleSurfaceArea/BinaryFiles/Filename" + return map(LoadModuleBinary, XmlList(XmlMsa, XmlTag)) + + +## Load a list of Module Non Processed Files. +# +# Read an input Module XML DOM object and return a list of Non Processed Files +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# +# @retvel NonProcessedFiles A list of Non Processed Files loaded from XmlMsa. +# +def LoadModuleNonProcessedFiles(XmlMsa): + XmlTag = "ModuleSurfaceArea/NonProcessedFiles/Filename" + return XmlElementList(XmlMsa, XmlTag) + + +## Load a new Module Package Dependency class object. +# +# Read an input XML PackageDependency DOM object and return an object of Package Dependency +# contained in the DOM object. +# +# @param XmlPackage A child XML DOM object in Module XML DOM. +# +# @retvel ModulePackageDependency A new Package Dependency object created by XmlPackage. +# +def LoadModulePackageDependency(XmlPackage): + ModulePackageDependency = ModulePackageDependencyClass() + + XmlTag = "PackageGuid" + PackageKey = XmlAttribute(XmlPackage, XmlTag) + + # + #TODO: Add resolution for Package name, package Version + # + ModulePackageDependency.PackageGuid = PackageKey + SetCommon(ModulePackageDependency, XmlPackage) + + return ModulePackageDependency + + +## Load a list of Module Package Dependencies. +# +# Read an input Module XML DOM object and return a list of Package Dependencies +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# +# @retvel PackageDependencies A list of Package Dependencies loaded from XmlMsa. +# +def LoadModulePackageDependencies(XmlMsa): + XmlTag = "ModuleSurfaceArea/PackageDependencies/Package" + return map(LoadModulePackageDependency, XmlList(XmlMsa, XmlTag)) + + +## Load a list of Module Protocols. +# +# Read an input Module XML DOM object and return a list of Protocols +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# +# @retvel Protocols A list of Protocols loaded from XmlMsa. +# +def LoadModuleProtocols(XmlMsa): + XmlTag = "ModuleSurfaceArea/Protocols/Protocol" + XmlProtocolList = XmlList(XmlMsa, XmlTag) + + XmlTag = "ModuleSurfaceArea/Protocols/ProtocolNotify" + XmlProtocolList += XmlList(XmlMsa, XmlTag) + + return map(LoadGuidProtocolPpiCommon, XmlProtocolList) + + +## Load a list of Module Ppis. +# +# Read an input Module XML DOM object and return a list of Ppis +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# +# @retvel Ppis A list of Ppis loaded from XmlMsa. +# +def LoadModulePpis(XmlMsa): + XmlTag = "ModuleSurfaceArea/PPIs/Ppi" + XmlPpiList = XmlList(XmlMsa, XmlTag) + + XmlTag = "ModuleSurfaceArea/PPIs/PpiNotify" + XmlPpiList += XmlList(XmlMsa, XmlTag) + + return map(LoadGuidProtocolPpiCommon, XmlPpiList) + + +## Load a new Module Event class object. +# +# Read an input XML Event DOM object and return an object of Event +# contained in the DOM object. +# +# @param XmlEvent A child XML DOM object in Module XML DOM. +# @param Type Specify the event type: SIGNAL_EVENT or CREATE_EVENT. +# +# @retvel ModuleEvent A new Event object created by XmlEvent. +# +def LoadModuleEvent(XmlEvent, Type): + ModuleEvent = ModuleEventClass() + + XmlTag = "EventTypes/EventType" + ModuleEvent.CName = XmlElement(XmlEvent, XmlTag) + + XmlTag = "EventGuidCName" + ModuleEvent.GuidCName = XmlAttribute(XmlEvent, XmlTag) + + ModuleEvent.Type = Type + + SetCommon(ModuleEvent, XmlEvent) + + return ModuleEvent + + +## Load a list of Module Events. +# +# Read an input Module XML DOM object and return a list of Events +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# +# @retvel Events A list of Events loaded from XmlMsa. +# +def LoadModuleEvents(XmlMsa): + ModuleEvents = [] + + XmlTag = "ModuleSurfaceArea/Events/CreateEvents/EventTypes" + for XmlCreateEvent in XmlList(XmlMsa, XmlTag): + ModuleEvent = LoadModuleEvent(XmlCreateEvent, "CREATE_EVENT") + ModuleEvents.append(ModuleEvent) + + XmlTag = "ModuleSurfaceArea/Events/SignalEvents/EventTypes" + for XmlCreateEvent in XmlList(XmlMsa, XmlTag): + ModuleEvent = LoadModuleEvent(XmlCreateEvent, "SIGNAL_EVENT") + ModuleEvents.append(ModuleEvent) + + return ModuleEvents + + +## Load a new Module Hob class object. +# +# Read an input XML Hob DOM object and return an object of Hob +# contained in the DOM object. +# +# @param XmlHob A child XML DOM object in Module XML DOM. +# +# @retvel ModuleHob A new Hob object created by XmlHob. +# +def LoadModuleHob(XmlHob): + ModuleHob = ModuleHobClass() + + XmlTag = "HobTypes/HobType" + ModuleHob.Type = XmlElement(XmlHob, XmlTag) + + XmlTag = "HobGuidCName" + ModuleHob.GuidCName = XmlAttribute(XmlHob, XmlTag) + + SetCommon(ModuleHob, XmlHob) + + return ModuleHob + + +## Load a list of Module Hobs. +# +# Read an input Module XML DOM object and return a list of Hobs +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# +# @retvel Hobs A list of Hobs loaded from XmlMsa. +# +def LoadModuleHobs(XmlMsa): + XmlTag = "ModuleSurfaceArea/Hobs/HobTypes" + return map(LoadModuleHob, XmlList(XmlMsa, XmlTag)) + + +## Load a new Module Variable class object. +# +# Read an input XML Variable DOM object and return an object of Variable +# contained in the DOM object. +# +# @param XmlVariable A child XML DOM object in Module XML DOM. +# +# @retvel ModuleVariable A new Variable object created by XmlVariable. +# +def LoadModuleVariable(XmlVariable): + ModuleVariable = ModuleVariableClass() + + XmlTag = "Variable/VariableName" + HexWordArray = XmlElement(XmlVariable, XmlTag).split() + try: + ModuleVariable.Name = "".join([unichr(int(a, 16)) for a in HexWordArray]) + except: + ModuleVariable.Name = "" + + XmlTag = "Variable/GuidC_Name" + ModuleVariable.GuidCName = XmlElement(XmlVariable, XmlTag) + + SetCommon(ModuleVariable, XmlVariable) + + return ModuleVariable + + +## Load a list of Module Variables. +# +# Read an input Module XML DOM object and return a list of Variables +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# +# @retvel Variables A list of Variables loaded from XmlMsa. +# +def LoadModuleVariables(XmlMsa): + XmlTag = "ModuleSurfaceArea/Variables/Variable" + return map(LoadModuleVariable, XmlList(XmlMsa, XmlTag)) + + +## Load a new Module Boot Mode class object. +# +# Read an input XML BootMode DOM object and return an object of Boot Mode +# contained in the DOM object. +# +# @param XmlBootMode A child XML DOM object in Module XML DOM. +# +# @retvel ModuleBootMode A new Boot Mode object created by XmlBootMode. +# +def LoadModuleBootMode(XmlBootMode): + ModuleBootMode = ModuleBootModeClass() + + XmlTag = "BootModeName" + ModuleBootMode.Name = XmlAttribute(XmlBootMode, XmlTag) + + SetCommon(ModuleBootMode, XmlBootMode) + + return ModuleBootMode + + +## Load a list of Module Boot Modes. +# +# Read an input Module XML DOM object and return a list of Boot Modes +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# +# @retvel BootModes A list of Boot Modes loaded from XmlMsa. +# +def LoadModuleBootModes(XmlMsa): + XmlTag = "ModuleSurfaceArea/BootModes/BootMode" + return map(LoadModuleBootMode, XmlList(XmlMsa, XmlTag)) + + +## Load a new Module System Table class object. +# +# Read an input XML SystemTable DOM object and return an object of System Table +# contained in the DOM object. +# +# @param XmlSystemTable A child XML DOM object in Module XML DOM. +# +# @retvel ModuleSystemTable A new System Table object created by XmlSystemTable. +# +def LoadModuleSystemTable(XmlSystemTable): + ModuleSystemTable = ModuleSystemTableClass() + + XmlTag = "SystemTable/SystemTableCName" + ModuleSystemTable.CName = XmlElement(XmlSystemTable, XmlTag) + + SetCommon(ModuleSystemTable, XmlSystemTable) + + return ModuleSystemTable + + +## Load a list of Module System Tables. +# +# Read an input Module XML DOM object and return a list of System Tables +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# +# @retvel SystemTables A list of System Tables loaded from XmlMsa. +# +def LoadModuleSystemTables(XmlMsa): + XmlTag = "ModuleSurfaceArea/SystemTables/SystemTableCNames" + return map(LoadModuleSystemTable, XmlList(XmlMsa, XmlTag)) + + +## Load a new Module Data Hub class object. +# +# Read an input XML DataHub DOM object and return an object of Data Hub +# contained in the DOM object. +# +# @param XmlDataHub A child XML DOM object in Module XML DOM. +# +# @retvel ModuleDataHub A new Data Hub object created by XmlDataHub. +# +def LoadModuleDataHub(XmlDataHub): + ModuleDataHub = ModuleDataHubClass() + + XmlTag = "DataHub/DataHubCName" + ModuleDataHub.CName = XmlElement(XmlDataHub, "DataHubCName") + + SetCommon(ModuleDataHub, XmlDataHub) + + return ModuleDataHub + + +## Load a list of Module Data Hubs. +# +# Read an input Module XML DOM object and return a list of Data Hubs +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# +# @retvel DataHubs A list of Data Hubs loaded from XmlMsa. +# +def LoadModuleDataHubs(XmlMsa): + XmlTag = "ModuleSurfaceArea/DataHubs/DataHubRecord" + return map(LoadModuleDataHub, XmlList(XmlMsa, XmlTag)) + + +## Load a new Module Hii Package class object. +# +# Read an input XML HiiPackage DOM object and return an object of Hii Package +# contained in the DOM object. +# +# @param XmlHiiPackage A child XML DOM object in Module XML DOM. +# +# @retvel ModuleHiiPackage A new Hii Package object created by XmlHiiPackage. +# +def LoadModuleHiiPackage(XmlHiiPackage): + ModuleHiiPackage = ModuleHiiPackageClass() + + XmlTag = "HiiPackage/HiiPackageCName" + ModuleHiiPackage.CName = XmlElement(XmlHiiPackage, "HiiCName") + + SetCommon(ModuleHiiPackage, XmlHiiPackage) + + return ModuleHiiPackage + + +## Load a list of Module Hii Packages. +# +# Read an input Module XML DOM object and return a list of Hii Packages +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# +# @retvel HiiPackages A list of Hii Packages loaded from XmlMsa. +# +def LoadModuleHiiPackages(XmlMsa): + XmlTag = "ModuleSurfaceArea/HiiPackages/HiiPackage" + return map(LoadModuleHiiPackage, XmlList(XmlMsa, XmlTag)) + + +## Load a list of Module Guids. +# +# Read an input Module XML DOM object and return a list of Guids +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# +# @retvel Guids A list of Guids loaded from XmlMsa. +# +def LoadModuleGuids(XmlMsa): + XmlTag = "ModuleSurfaceArea/Guids/GuidCNames" + return map(LoadGuidProtocolPpiCommon, XmlList(XmlMsa, XmlTag)) + + +## Load a list of Module Pcd Codes. +# +# Read an input Module XML DOM object and return a list of Pcd Codes +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# +# @retvel PcdCodes A list of Pcd Codes loaded from XmlMsa. +# +def LoadModulePcdCodes(XmlMsa): + XmlTag = "ModuleSurfaceArea/PcdCoded/PcdEntry" + return map(LoadPcd, XmlList(XmlMsa, XmlTag)) + + +## Load a list of Module Extern Images. +# +# Read an input Module XML DOM object and return a list of Extern Images +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# +# @retvel ExternImages A list of Extern Images loaded from XmlMsa. +# +def LoadModuleExternImages(XmlMsa): + ModuleExternImages = [] + + XmlTag = "ModuleSurfaceArea/Externs/Extern" + for XmlExtern in XmlList(XmlMsa, XmlTag): + XmlTag = "Extern/ModuleEntryPoint" + ModuleEntryPoint = XmlElement(XmlExtern, XmlTag) + XmlTag = "Extern/ModuleUnloadImage" + ModuleUnloadImage = XmlElement(XmlExtern, XmlTag) + if ModuleEntryPoint == "" and ModuleUnloadImage == "": + continue + + ModuleExtern = ModuleExternImageClass() + ModuleExtern.ModuleEntryPoint = ModuleEntryPoint + ModuleExtern.ModuleUnloadImage = ModuleUnloadImage + ModuleExternImages.append(ModuleExtern) + + return ModuleExternImages + + +## Load a list of Module Extern Libraries. +# +# Read an input Module XML DOM object and return a list of Extern Libraries +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# +# @retvel ExternLibraries A list of Extern Libraries loaded from XmlMsa. +# +def LoadModuleExternLibraries(XmlMsa): + ModuleExternLibraries = [] + + XmlTag = "ModuleSurfaceArea/Externs/Extern" + for XmlExtern in XmlList(XmlMsa, XmlTag): + XmlTag = "Extern/Constructor" + Constructor = XmlElement(XmlExtern, XmlTag) + XmlTag = "Extern/Destructor" + Destructor = XmlElement(XmlExtern, XmlTag) + if Constructor == "" and Destructor == "": + continue + + ModuleExtern = ModuleExternLibraryClass() + ModuleExtern.Constructor = Constructor + ModuleExtern.Destructor = Destructor + ModuleExternLibraries.append(ModuleExtern) + + return ModuleExternLibraries + + +## Load a list of Module Extern Drivers. +# +# Read an input Module XML DOM object and return a list of Extern Drivers +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# +# @retvel ExternDrivers A list of Extern Drivers loaded from XmlMsa. +# +def LoadModuleExternDrivers(XmlMsa): + ModuleExternDrivers = [] + + XmlTag = "ModuleSurfaceArea/Externs/Extern" + for XmlExtern in XmlList(XmlMsa, XmlTag): + XmlTag = "Extern/DriverBinding" + DriverBinding = XmlElement(XmlExtern, XmlTag) + XmlTag = "Extern/ComponentName" + ComponentName = XmlElement(XmlExtern, XmlTag) + XmlTag = "Extern/DriverConfig" + DriverConfig = XmlElement(XmlExtern, XmlTag) + XmlTag = "Extern/DriverDiag" + DriverDiag = XmlElement(XmlExtern, XmlTag) + if DriverBinding == "": + continue + + ModuleExtern = ModuleExternDriverClass() + ModuleExtern.DriverBinding = DriverBinding + ModuleExtern.ComponentName = ComponentName + ModuleExtern.DriverConfig = DriverConfig + ModuleExtern.DriverDiag = DriverDiag + ModuleExternDrivers.append(ModuleExtern) + + return ModuleExternDrivers + + +## Load a list of Module Extern Call Backs. +# +# Read an input Module XML DOM object and return a list of Extern Call Backs +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# +# @retvel ExternCallBacks A list of Extern Call Backs loaded from XmlMsa. +# +def LoadModuleExternCallBacks(XmlMsa): + ModuleExternCallBacks = [] + + XmlTag = "ModuleSurfaceArea/Externs/Extern" + for XmlExtern in XmlList(XmlMsa, XmlTag): + XmlTag = "Extern/SetVirtualAddressMapCallBack" + SetVirtualAddressMap = XmlElement(XmlExtern, XmlTag) + XmlTag = "Extern/ExitBootServicesCallBack" + ExitBootServices = XmlElement(XmlExtern, XmlTag) + if SetVirtualAddressMap == "" and ExitBootServices == "": + continue + + ModuleExtern = ModuleExternCallBackClass() + ModuleExtern.ExitBootServicesCallBack = ExitBootServices + ModuleExtern.SetVirtualAddressMapCallBack = SetVirtualAddressMap + ModuleExternCallBacks.append(ModuleExtern) + + return ModuleExternCallBacks + + +## Load a list of Module Build Options. +# +# Read an input Module XML DOM object and return a list of Build Options +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# +# @retvel BuildOptions A list of Build Options loaded from XmlMsa. +# +def LoadModuleBuildOptions(XmlMsa): + XmlTag = "ModuleSurfaceArea/ModuleBuildOptions/Options/Option" + return map(LoadBuildOption, XmlList(XmlMsa, XmlTag)) + + +## Load a list of Module User Extensions. +# +# Read an input Module XML DOM object and return a list of User Extensions +# contained in the DOM object. +# +# @param XmlMsa An XML DOM object read from MSA file. +# +# @retvel UserExtensions A list of User Extensions loaded from XmlMsa. +# +def LoadModuleUserExtensions(XmlMsa): + XmlTag = "ModuleSurfaceArea/UserExtensions" + return map(LoadUserExtensions, XmlList(XmlMsa, XmlTag)) + +## Load a new Module class object. +# +# Read an input MSA File and return a new Module class Object. +# +# @param MsaFileName An XML DOM object read from MSA file. +# +# @retvel Module A new Module class object loaded from MSA File. +# +def LoadMsa(MsaFileName): + XmlMsa = XmlParseFile(MsaFileName) + EdkLogger.verbose("Load MSA File: %s" % MsaFileName) + + Module = ModuleClass() + Module.Header = LoadModuleHeader(XmlMsa, MsaFileName) + Module.LibraryClasses = LoadModuleLibraryClasses(XmlMsa) + Module.Sources = LoadModuleSources(XmlMsa) + Module.BinaryFiles = LoadModuleBinaries(XmlMsa) + Module.NonProcessedFiles = LoadModuleNonProcessedFiles(XmlMsa) + Module.PackageDependencies = LoadModulePackageDependencies(XmlMsa) + Module.Protocols = LoadModuleProtocols(XmlMsa) + Module.Ppis = LoadModulePpis(XmlMsa) + Module.Events = LoadModuleEvents(XmlMsa) + Module.Hobs = LoadModuleHobs(XmlMsa) + Module.Variables = LoadModuleVariables(XmlMsa) + Module.BootModes = LoadModuleBootModes(XmlMsa) + Module.SystemTables = LoadModuleSystemTables(XmlMsa) + Module.DataHubs = LoadModuleDataHubs(XmlMsa) + Module.HiiPackages = LoadModuleHiiPackages(XmlMsa) + Module.Guids = LoadModuleGuids(XmlMsa) + Module.PcdCodes = LoadModulePcdCodes(XmlMsa) + Module.ExternImages = LoadModuleExternImages(XmlMsa) + Module.ExternLibraries = LoadModuleExternLibraries(XmlMsa) + Module.ExternDrivers = LoadModuleExternDrivers(XmlMsa) + Module.ExternCallBacks = LoadModuleExternCallBacks(XmlMsa) + Module.BuildOptions = LoadModuleBuildOptions(XmlMsa) + Module.UserExtensions = LoadModuleUserExtensions(XmlMsa) + + return Module + + +# This acts like the main() function for the script, unless it is 'import'ed +# into another script. +if __name__ == '__main__': + pass \ No newline at end of file diff --git a/BaseTools/Source/Python/msa2inf/Msa2Inf.py b/BaseTools/Source/Python/msa2inf/Msa2Inf.py new file mode 100644 index 0000000000..5873b1d198 --- /dev/null +++ b/BaseTools/Source/Python/msa2inf/Msa2Inf.py @@ -0,0 +1,44 @@ +## @file +# Convert an XML-based MSA file to a text-based INF file. +# +# Copyright (c) 2007, 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 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 sys +from Common.MigrationUtilities import * +from LoadMsa import LoadMsa +from StoreInf import StoreInf +from ConvertModule import ConvertMsaModuleToInfModule + +## 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(): + try: + Options, InputFile = MigrationOptionParser("MSA", "INF", "%prog") + Module = LoadMsa(InputFile) + ConvertMsaModuleToInfModule(Module) + StoreInf(Options.OutputFile, Module) + return 0 + except Exception, e: + print e + return 1 + +if __name__ == '__main__': + sys.exit(Main()) diff --git a/BaseTools/Source/Python/msa2inf/StoreInf.py b/BaseTools/Source/Python/msa2inf/StoreInf.py new file mode 100644 index 0000000000..bb58dc2f2f --- /dev/null +++ b/BaseTools/Source/Python/msa2inf/StoreInf.py @@ -0,0 +1,442 @@ +## @file +# Store a Module class object to an INF file. +# +# Copyright (c) 2007, 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 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 +# +from LoadMsa import LoadMsa +from CommonDataClass.ModuleClass import * +from Common.MigrationUtilities import * + +## Get the produced library class. +# +# Return the item of Library Class based on Library . +# +# @param LibraryClasses A list of library classes the module produces. +# +# @retval LibraryClassItem A text format library class item. +# +def GetModuleLibraryClass(LibraryClasses): + ProducedLibraryClasses = [] + for LibraryClass in LibraryClasses: + ProducedLibraryClass = LibraryClass.LibraryClass + SupportedModueTypes = " ".join(LibraryClass.SupModuleList) + if SupportedModueTypes != "": + ProducedLibraryClass += "|" + SupportedModueTypes + ProducedLibraryClasses.append(ProducedLibraryClass) + + return "|".join(ProducedLibraryClasses) + + +## Store Defines section. +# +# Write [Defines] section to the InfFile based on Module class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param InfFile The output INF file to store the Defines section. +# @param Module An input Module class object. +# +def StoreModuleDefinesSection(InfFile, Module): + ModuleHeader = Module.Header + + DefinesTupleList = [] + DefinesTupleList.append(("INF_VERSION", ModuleHeader.InfVersion)) + + if ModuleHeader.Name != "": + DefinesTupleList.append(("BASE_NAME", ModuleHeader.Name)) + + if ModuleHeader.Guid != "": + DefinesTupleList.append(("FILE_GUID", ModuleHeader.Guid)) + + if ModuleHeader.Version != "": + DefinesTupleList.append(("VERSION_STRING", ModuleHeader.Version)) + + if ModuleHeader.ModuleType != "": + DefinesTupleList.append(("MODULE_TYPE", ModuleHeader.ModuleType)) + + if ModuleHeader.EfiSpecificationVersion != "": + DefinesTupleList.append(("EFI_SPECIFICATION_VERSION", ModuleHeader.EfiSpecificationVersion)) + + if ModuleHeader.EdkReleaseVersion != "": + DefinesTupleList.append(("EDK_RELEASE_VERSION", ModuleHeader.EdkReleaseVersion)) + + ProducedLibraryClass = GetModuleLibraryClass(ModuleHeader.LibraryClass) + if ProducedLibraryClass != "": + DefinesTupleList.append(("LIBRARY_CLASS", ProducedLibraryClass)) + + if ModuleHeader.MakefileName != "": + DefinesTupleList.append(("MAKEFILE_NAME", ModuleHeader.MakeFileName)) + + if ModuleHeader.PcdIsDriver != "": + DefinesTupleList.append(("PCD_DRIVER", "TRUE")) + + if len(Module.ExternImages) > 0: + ModuleEntryPoint = Module.ExternImages[0].ModuleEntryPoint + ModuleUnloadImage = Module.ExternImages[0].ModuleUnloadImage + if ModuleEntryPoint != "": + DefinesTupleList.append(("ENTRY_POINT", ModuleEntryPoint)) + if ModuleUnloadImage != "": + DefinesTupleList.append(("UNLOAD_IMAGE", ModuleUnloadImage)) + + if len(Module.ExternLibraries) > 0: + Constructor = Module.ExternLibraries[0].Constructor + Destructor = Module.ExternLibraries[0].Destructor + if Constructor != "": + DefinesTupleList.append(("CONSTRUCTOR", Constructor)) + if Destructor != "": + DefinesTupleList.append(("DESTRUCTOR", Destructor)) + + StoreDefinesSection(InfFile, DefinesTupleList) + + +## Return a Module Source Item. +# +# Read the input ModuleSourceFile class object and return one line of Source Item. +# +# @param ModuleSourceFile An input ModuleSourceFile class object. +# +# @retval SourceItem A Module Source Item. +# +def GetModuleSourceItem(ModuleSourceFile): + Source = [] + Source.append(ModuleSourceFile.SourceFile) + Source.append(ModuleSourceFile.ToolChainFamily) + Source.append(ModuleSourceFile.TagName) + Source.append(ModuleSourceFile.ToolCode) + Source.append(ModuleSourceFile.FeatureFlag) + return "|".join(Source).rstrip("|") + + +## Store Sources section. +# +# Write [Sources] section to the InfFile based on Module class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param InfFile The output INF file to store the Sources section. +# @param Module An input Module class object. +# +def StoreModuleSourcesSection(InfFile, Module): + Section = GetSection("Sources", GetModuleSourceItem, Module.Sources) + StoreTextFile(InfFile, Section) + + +## Return a Module Binary Item. +# +# Read the input ModuleBinaryFile class object and return one line of Binary Item. +# +# @param ModuleBinaryFile An input ModuleBinaryFile class object. +# +# @retval BinaryItem A Module Binary Item. +# +def GetModuleBinaryItem(ModuleBinaryFile): + Binary = [] + Binary.append(ModuleBinaryFile.FileType) + Binary.append(ModuleBinaryFile.BinaryFile) + Binary.append(ModuleBinaryFile.Target) + Binary.append(ModuleBinaryFile.FeatureFlag) + return "|".join(Binary).rstrip("|") + + +## Store Binaries section. +# +# Write [Binaries] section to the InfFile based on Module class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param InfFile The output INF file to store the Binaries section. +# @param Module An input Module class object. +# +def StoreModuleBinariesSection(InfFile, Module): + Section = GetSection("Binaries", GetModuleBinaryItem, Module.Binaries) + StoreTextFile(InfFile, Section) + + +## Return a Module Library Class Item. +# +# Read the input LibraryClass class object and return one line of Library Class Item. +# +# @param LibraryClass An input LibraryClass class object. +# +# @retval LibraryClassItem A Module Library Class Item. +# +def GetModuleLibraryClassItem(LibraryClass): + if "ALWAYS_PRODUCED" in LibraryClass.Usage: + return "" + + LibraryClassList = [] + LibraryClassList.append(LibraryClass.LibraryClass) + LibraryClassList.append(LibraryClass.RecommendedInstance) + LibraryClassList.append(LibraryClass.FeatureFlag) + + return "|".join(LibraryClassList).rstrip("|") + + +## Store Library Classes section. +# +# Write [LibraryClasses] section to the InfFile based on Module class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param InfFile The output INF file to store the Library Classes section. +# @param Module An input Module class object. +# +def StoreModuleLibraryClassesSection(InfFile, Module): + Section = GetSection("LibraryClasses", GetModuleLibraryClassItem, Module.LibraryClasses) + StoreTextFile(InfFile, Section) + + +## Return a Module Package Item. +# +# Read the input PackageDependency class object and return one line of Package Item. +# +# @param PackageDependency An input PackageDependency class object. +# +# @retval PackageItem A Module Package Item. +# +def GetModulePackageItem(PackageDependency): + return PackageDependency.FilePath + + +## Store Packages section. +# +# Write [Packages] section to the InfFile based on Module class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param InfFile The output INF file to store the Packages section. +# @param Module An input Module class object. +# +def StoreModulePackagesSection(InfFile, Module): + Section = GetSection("Packages", GetModulePackageItem, Module.PackageDependencies) + StoreTextFile(InfFile, Section) + + +## Return a Module Guid C Name Item. +# +# Read the input Guid class object and return one line of Guid C Name Item. +# +# @param Guid An input Guid class object. +# +# @retval GuidCNameItem A Module Guid C Name Item. +# +def GetModuleGuidCNameItem(Guid): + try: + return Guid.GuidCName + except: + return Guid.CName + + +## Store Protocols section. +# +# Write [Protocols] section to the InfFile based on Module class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param InfFile The output INF file to store the Protocols section. +# @param Module An input Module class object. +# +def StoreModuleProtocolsSection(InfFile, Module): + Section = GetSection("Protocols", GetModuleGuidCNameItem, Module.Protocols) + StoreTextFile(InfFile, Section) + + +## Store Ppis section. +# +# Write [Ppis] section to the InfFile based on Module class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param InfFile The output INF file to store the Ppis section. +# @param Module An input Module class object. +# +def StoreModulePpisSection(InfFile, Module): + Section = GetSection("Ppis", GetModuleGuidCNameItem, Module.Ppis) + StoreTextFile(InfFile, Section) + + +## Store Guids section. +# +# Write [Guids] section to the InfFile based on Module class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param InfFile The output INF file to store the Guids section. +# @param Module An input Module class object. +# +def StoreModuleGuidsSection(InfFile, Module): + Guids = [] + Guids += Module.Guids + Guids += Module.Events + Guids += Module.Hobs + Guids += Module.Variables + Guids += Module.SystemTables + Guids += Module.DataHubs + Guids += Module.HiiPackages + Section = GetSection("Guids", GetModuleGuidCNameItem, Guids) + StoreTextFile(InfFile, Section) + + +## Return a Module Pcd Item. +# +# Read the input Pcd class object and return one line of Pcd Item. +# +# @param Pcd An input Pcd class object. +# +# @retval PcdItem A Module Pcd Item. +# +def GetModulePcdItem(Pcd): + PcdItem = "%s.%s" % (Pcd.TokenSpaceGuidCName, Pcd.CName) + if Pcd.DefaultValue != "": + PcdItem = "%s|%s" % (PcdItem, Pcd.DefaultValue) + + return PcdItem + + +## DEC Pcd Section Name dictionary indexed by PCD Item Type. +mInfPcdSectionNameDict = { + "FEATURE_FLAG" : "FeaturePcd", + "FIXED_AT_BUILD" : "FixedPcd", + "PATCHABLE_IN_MODULE" : "PatchPcd", + "DYNAMIC" : "Pcd", + "DYNAMIC_EX" : "PcdEx" + } + +## Store Pcds section. +# +# Write [(PcdType)] section to the InfFile based on Module class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param InfFile The output INF file to store the Pcds section. +# @param Module An input Module class object. +# +def StoreModulePcdsSection(InfFile, Module): + PcdsDict = {} + for Pcd in Module.PcdCodes: + PcdSectionName = mInfPcdSectionNameDict.get(Pcd.ItemType) + if PcdSectionName: + PcdsDict.setdefault(PcdSectionName, []).append(Pcd) + else: + EdkLogger.info("Unknown Pcd Item Type: %s" % Pcd.ItemType) + + Section = "" + for PcdSectionName in PcdsDict: + Pcds = PcdsDict[PcdSectionName] + Section += GetSection(PcdSectionName, GetModulePcdItem, Pcds) + Section += "\n" + + StoreTextFile(InfFile, Section) + + +## Return a Module Depex Item. +# +# Read the input Depex class object and return one line of Depex Item. +# +# @param Depex An input Depex class object. +# +# @retval DepexItem A Module Depex Item. +# +def GetModuleDepexItem(Depex): + return Depex.Depex + + +## Store Depex section. +# +# Write [Depex] section to the InfFile based on Module class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param InfFile The output INF file to store the Depex section. +# @param Module An input Module class object. +# +def StoreModuleDepexSection(InfFile, Module): + Section = GetSection("Depex", GetModuleDepexItem, Module.Depex) + StoreTextFile(InfFile, Section) + + +## Return a Module Build Option Item. +# +# Read the input BuildOption class object and return one line of Build Option Item. +# +# @param BuildOption An input BuildOption class object. +# +# @retval BuildOptionItem A Module Build Option Item. +# +def GetModuleBuildOptionItem(BuildOption): + BuildTarget = BuildOption.BuildTarget + if BuildTarget == "": + BuildTarget = "*" + + TagName = BuildOption.TagName + if TagName == "": + TagName = "*" + + ToolCode = BuildOption.ToolCode + if ToolCode == "": + ToolCode = "*" + + Item = "_".join((BuildTarget, TagName, "*", ToolCode, "Flag")) + + ToolChainFamily = BuildOption.ToolChainFamily + if ToolChainFamily != "": + Item = "%s:%s" % (ToolChainFamily, Item) + + return "%-30s = %s" % (Item, BuildOption.Option) + + +## Store Build Options section. +# +# Write [BuildOptions] section to the InfFile based on Module class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param InfFile The output INF file to store the Build Options section. +# @param Module An input Module class object. +# +def StoreModuleBuildOptionsSection(InfFile, Module): + Section = GetSection("BuildOption", GetModuleBuildOptionItem, Module.BuildOptions) + StoreTextFile(InfFile, Section) + + +## Store User Extensions section. +# +# Write [UserExtensions] section to the InfFile based on Module class object. +# +# @param InfFile The output INF file to store the User Extensions section. +# @param Module An input Module class object. +# +def StoreModuleUserExtensionsSection(InfFile, Module): + Section = "".join(map(GetUserExtensions, Module.UserExtensions)) + StoreTextFile(InfFile, Section) + + +## Store a Module class object to a new INF file. +# +# Read an input Module class object and save the contents to a new INF file. +# +# @param INFFileName The output INF file. +# @param Module An input Package class object. +# +def StoreInf(InfFileName, Module): + InfFile = open(InfFileName, "w+") + EdkLogger.info("Save file to %s" % InfFileName) + + StoreHeader(InfFile, Module.Header) + StoreModuleDefinesSection(InfFile, Module) + StoreModuleSourcesSection(InfFile, Module) + StoreModuleBinariesSection(InfFile, Module) + StoreModulePackagesSection(InfFile, Module) + StoreModuleLibraryClassesSection(InfFile, Module) + StoreModuleProtocolsSection(InfFile, Module) + StoreModulePpisSection(InfFile, Module) + StoreModuleGuidsSection(InfFile, Module) + StoreModulePcdsSection(InfFile, Module) + StoreModuleDepexSection(InfFile, Module) + StoreModuleBuildOptionsSection(InfFile, Module) + StoreModuleUserExtensionsSection(InfFile, Module) + + InfFile.close() + +if __name__ == '__main__': + pass diff --git a/BaseTools/Source/Python/msa2inf/__init__.py b/BaseTools/Source/Python/msa2inf/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/BaseTools/Source/Python/spd2dec/ConvertPackage.py b/BaseTools/Source/Python/spd2dec/ConvertPackage.py new file mode 100644 index 0000000000..57bc098bfa --- /dev/null +++ b/BaseTools/Source/Python/spd2dec/ConvertPackage.py @@ -0,0 +1,66 @@ +## @file +# Convert an SPD Package class object ot a DEC Package class object by filling +# some fields required by DEC file. +# +# Copyright (c) 2007, 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 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 +from Common.MigrationUtilities import * +from LoadSpd import LoadSpd +from StoreDec import StoreDec + +#The default DEC version number tool generates. +gDecVersion = "0x00010005" + + +## Add required version information. +# +# Add the default DEC specification version to Package class object. +# +# @param Package An input Package class object. +# +def AddPackageMiscVersion(Package): + PackageHeader = Package.Header + PackageHeader.DecSpecification = gDecVersion + +## Add package include information. +# +# Adds the default "Include" folder to if that directory exists. +# +# @param Package An input Package class object. +# +def AddPackageInclude(Package): + PackageDir = os.path.dirname(Package.Header.FullPath) + DefaultIncludeDir = os.path.join(PackageDir, "Include") + if os.path.exists(DefaultIncludeDir): + Include = IncludeClass() + Include.FilePath = "Include" + Package.Includes.insert(0, Include) + +## Convert SPD Package class object to DEC Package class object. +# +# Convert SPD Package class ojbect to DEC Package class object by filling in +# several information required by DEC file. +# +# @param Package An input Package class object. +# +def ConvertSpdPackageToDecPackage(Package): + AddPackageMiscVersion(Package) + AddPackageInclude(Package) + +# This acts like the main() function for the script, unless it is 'import'ed +# into another script. +if __name__ == '__main__': + pass + \ No newline at end of file diff --git a/BaseTools/Source/Python/spd2dec/LoadSpd.py b/BaseTools/Source/Python/spd2dec/LoadSpd.py new file mode 100644 index 0000000000..e94e7fc317 --- /dev/null +++ b/BaseTools/Source/Python/spd2dec/LoadSpd.py @@ -0,0 +1,273 @@ +## @file +# Open an SPD file and load all its contents to a PackageClass object. +# +# Copyright (c) 2007, 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 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 +from Common.XmlRoutines import * +from Common.MigrationUtilities import * +from CommonDataClass.PackageClass import * + + +## Load a list of Package Cloned Records. +# +# Read an input Package XML DOM object and return a list of Cloned Records +# contained in the DOM object. +# +# @param XmlSpd An XML DOM object read from SPD file. +# +# @retvel ClonedRecords A list of Cloned Records loaded from XmlSpd. +# +def LoadPackageClonedRecords(XmlSpd): + XmlTag = "PackageSurfaceArea/PackageDefinitions/ClonedFrom/Cloned" + return map(LoadClonedRecord, XmlList(XmlSpd, XmlTag)) + + +## Load Package Header. +# +# Read an input Package XML DOM object and return Package Header class object +# contained in the DOM object. +# +# @param XmlSpd An XML DOM object read from SPD file. +# @param SpdFileName The file path of SPD File. +# +# @retvel PackageHeader A new Package Header object loaded from XmlSpd. +# +def LoadPackageHeader(XmlSpd, SpdFileName): + PackageHeader = PackageHeaderClass() + + XmlTag = "PackageSurfaceArea/SpdHeader" + SpdHeader = XmlNode(XmlSpd, XmlTag) + + SetIdentification(PackageHeader, SpdHeader, "PackageName", SpdFileName) + SetCommonHeader(PackageHeader, SpdHeader) + + XmlTag = "PackageSurfaceArea/PackageDefinitions/ReadOnly" + if XmlElement(XmlSpd, XmlTag).lower() == "true": + PackageHeader.ReadOnly = True + + XmlTag = "PackageSurfaceArea/PackageDefinitions/RePackage" + if XmlElement(XmlSpd, XmlTag).lower() == "true": + PackageHeader.RePackage = True + + PackageHeader.ClonedFrom = LoadPackageClonedRecords(XmlSpd) + + return PackageHeader + + +## Load a list of Package Library Classes. +# +# Read an input Package XML DOM object and return a list of Library Classes +# contained in the DOM object. +# +# @param XmlSpd An XML DOM object read from SPD file. +# +# @retvel LibraryClasses A list of Library Classes loaded from XmlSpd. +# +def LoadPackageLibraryClasses(XmlSpd): + XmlTag = "PackageSurfaceArea/LibraryClassDeclarations/LibraryClass" + return map(LoadLibraryClass, XmlList(XmlSpd, XmlTag)) + + +## Load a new Package Industry Std Header class object. +# +# Read an input XML IndustryStdHeader DOM object and return an object of +# Industry Std Header contained in the DOM object. +# +# @param XmlIndustryStdHeader A child XML DOM object in Package XML DOM. +# +# @retvel PackageIndustryStdHeader A new Industry Std Header object created by XmlIndustryStdHeader. +# +def LoadPackageIndustryStdHeader(XmlIndustryStdHeader): + PackageIndustryStdHeader = PackageIndustryStdHeaderClass() + + XmlTag = "Name" + Name = XmlAttribute(XmlIndustryStdHeader, XmlTag) + PackageIndustryStdHeader.Name = Name + + XmlTag = "IndustryStdHeader/IncludeHeader" + IncludeHeader = XmlElement(XmlIndustryStdHeader, XmlTag) + PackageIndustryStdHeader.IncludeHeader = IncludeHeader + + SetCommon(PackageIndustryStdHeader, XmlIndustryStdHeader) + + return PackageIndustryStdHeader + + +## Load a list of Package Industry Std Headers. +# +# Read an input Package XML DOM object and return a list of Industry Std Headers +# contained in the DOM object. +# +# @param XmlSpd An XML DOM object read from SPD file. +# +# @retvel IndustryStdHeaders A list of Industry Std Headers loaded from XmlSpd. +# +def LoadPackageIndustryStdHeaders(XmlSpd): + XmlTag = "PackageSurfaceArea/IndustryStdIncludes/IndustryStdHeader" + return map(LoadPackageIndustryStdHeader, XmlList(XmlSpd, XmlTag)) + + +## Load a list of Package Module Files. +# +# Read an input Package XML DOM object and return a list of Module Files +# contained in the DOM object. +# +# @param XmlSpd An XML DOM object read from SPD file. +# +# @retvel ModuleFiles A list of Module Files loaded from XmlSpd. +# +def LoadPackageModuleFiles(XmlSpd): + XmlTag = "PackageSurfaceArea/MsaFiles/Filename" + return XmlElementList(XmlSpd, XmlTag) + + +## Load a new Package Include Pkg Header class object. +# +# Read an input XML IncludePkgHeader DOM object and return an object of Include +# Package Header contained in the DOM object. +# +# @param XmlPackageIncludeHeader A child XML DOM object in Package XML DOM. +# +# @retvel PackageIncludePkgHeader A new Include Pkg Header object created by +# XmlPackageIncludeHeader. +# +def LoadPackageIncludePkgHeader(XmlPackageIncludeHeader): + PackageIncludeHeader = PackageIncludePkgHeaderClass() + + IncludeHeader = XmlElementData(XmlPackageIncludeHeader) + PackageIncludeHeader.IncludeHeader = IncludeHeader + + XmlTag = "ModuleType" + ModuleTypes = XmlAttribute(XmlPackageIncludeHeader, XmlTag) + PackageIncludeHeader.ModuleType = ModuleTypes.split() + + return PackageIncludeHeader + + +## Load a list of Package Include Pkg Headers. +# +# Read an input Package XML DOM object and return a list of Include Pkg Headers +# contained in the DOM object. +# +# @param XmlSpd An XML DOM object read from SPD file. +# +# @retvel IncludePkgHeaders A list of Include Pkg Headers loaded from XmlSpd. +# +def LoadPackageIncludePkgHeaders(XmlSpd): + XmlTag = "PackageSurfaceArea/PackageHeaders/IncludePkgHeader" + return map(LoadPackageIncludePkgHeader, XmlList(XmlSpd, XmlTag)) + + +## Load a list of Package Guid Declarations. +# +# Read an input Package XML DOM object and return a list of Guid Declarations +# contained in the DOM object. +# +# @param XmlSpd An XML DOM object read from SPD file. +# +# @retvel GuidDeclarations A list of Guid Declarations loaded from XmlSpd. +# +def LoadPackageGuidDeclarations(XmlSpd): + XmlTag = "PackageSurfaceArea/GuidDeclarations/Entry" + return map(LoadGuidProtocolPpiCommon, XmlList(XmlSpd, XmlTag)) + + +## Load a list of Package Protocol Declarations. +# +# Read an input Package XML DOM object and return a list of Protocol Declarations +# contained in the DOM object. +# +# @param XmlSpd An XML DOM object read from SPD file. +# +# @retvel ProtocolDeclarations A list of Protocol Declarations loaded from XmlSpd. +# +def LoadPackageProtocolDeclarations(XmlSpd): + XmlTag = "PackageSurfaceArea/ProtocolDeclarations/Entry" + return map(LoadGuidProtocolPpiCommon, XmlList(XmlSpd, XmlTag)) + + +## Load a list of Package Ppi Declarations. +# +# Read an input Package XML DOM object and return a list of Ppi Declarations +# contained in the DOM object. +# +# @param XmlSpd An XML DOM object read from SPD file. +# +# @retvel PpiDeclarations A list of Ppi Declarations loaded from XmlSpd. +# +def LoadPackagePpiDeclarations(XmlSpd): + XmlTag = "PackageSurfaceArea/PpiDeclarations/Entry" + return map(LoadGuidProtocolPpiCommon, XmlList(XmlSpd, XmlTag)) + + +## Load a list of Package Pcd Declarations. +# +# Read an input Package XML DOM object and return a list of Pcd Declarations +# contained in the DOM object. +# +# @param XmlSpd An XML DOM object read from SPD file. +# +# @retvel PcdDeclarations A list of Pcd Declarations loaded from XmlSpd. +# +def LoadPackagePcdDeclarations(XmlSpd): + XmlTag = "PackageSurfaceArea/PcdDeclarations/PcdEntry" + return map(LoadPcd, XmlList(XmlSpd, XmlTag)) + + +## Load a list of Package User Extensions. +# +# Read an input Package XML DOM object and return a list of User Extensions +# contained in the DOM object. +# +# @param XmlSpd An XML DOM object read from SPD file. +# +# @retvel UserExtensions A list of User Extensions loaded from XmlSpd. +# +def LoadPackageUserExtensions(XmlSpd): + XmlTag = "PackageSurfaceArea/UserExtensions" + return map(LoadUserExtensions, XmlList(XmlSpd, XmlTag)) + + +## Load a new Package class object. +# +# Read an input SPD File and return a new Package class Object. +# +# @param SpdFileName An XML DOM object read from SPD file. +# +# @retvel Package A new Module class object loaded from SPD File. +# +def LoadSpd(SpdFileName): + XmlSpd = XmlParseFile(SpdFileName) + EdkLogger.verbose("Xml Object loaded for file %s" % SpdFileName) + + Package = PackageClass() + Package.Header = LoadPackageHeader(XmlSpd, SpdFileName) + Package.LibraryClassDeclarations = LoadPackageLibraryClasses(XmlSpd) + Package.IndustryStdHeaders = LoadPackageIndustryStdHeaders(XmlSpd) + Package.ModuleFiles = LoadPackageModuleFiles(XmlSpd) + Package.PackageIncludePkgHeaders = LoadPackageIncludePkgHeaders(XmlSpd) + Package.GuidDeclarations = LoadPackageGuidDeclarations(XmlSpd) + Package.ProtocolDeclarations = LoadPackageProtocolDeclarations(XmlSpd) + Package.PpiDeclarations = LoadPackagePpiDeclarations(XmlSpd) + Package.PcdDeclarations = LoadPackagePcdDeclarations(XmlSpd) + Package.UserExtensions = LoadPackageUserExtensions(XmlSpd) + + return Package + + +# This acts like the main() function for the script, unless it is 'import'ed +# into another script. +if __name__ == '__main__': + pass diff --git a/BaseTools/Source/Python/spd2dec/Spd2Dec.py b/BaseTools/Source/Python/spd2dec/Spd2Dec.py new file mode 100644 index 0000000000..46d058344b --- /dev/null +++ b/BaseTools/Source/Python/spd2dec/Spd2Dec.py @@ -0,0 +1,46 @@ +## @file +# Convert an XML-based SPD file to a text-based DEC file. +# +# Copyright (c) 2007, 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 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 sys +from Common.MigrationUtilities import * +from LoadSpd import LoadSpd +from StoreDec import StoreDec +from ConvertPackage import ConvertSpdPackageToDecPackage + +## 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(): + try: + Options, InputFile = MigrationOptionParser("SPD", "DEC", "%prog") + Package = LoadSpd(InputFile) + ConvertSpdPackageToDecPackage(Package) + StoreDec(Options.OutputFile, Package) + return 0 + except Exception, e: + print e + return 1 + +if __name__ == '__main__': + sys.exit(Main()) + + diff --git a/BaseTools/Source/Python/spd2dec/StoreDec.py b/BaseTools/Source/Python/spd2dec/StoreDec.py new file mode 100644 index 0000000000..67cbd11e9b --- /dev/null +++ b/BaseTools/Source/Python/spd2dec/StoreDec.py @@ -0,0 +1,247 @@ +## @file +# Store a Package class object to a DEC file. +# +# Copyright (c) 2007, 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 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 +from Common.MigrationUtilities import * +from LoadSpd import LoadSpd +from CommonDataClass.PackageClass import * + + +## Store Defines section. +# +# Write [Defines] section to the DecFile based on Package class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param DecFile The output DEC file to store the Defines section. +# @param Package An input Package class object. +# +def StorePackageDefinesSection(DecFile, Package): + DefinesTupleList = [] + DefinesTupleList.append(("DEC_VERSION", Package.Header.DecSpecification)) + DefinesTupleList.append(("PACKAGE_NAME", Package.Header.Name)) + DefinesTupleList.append(("PACKAGE_GUID", Package.Header.Guid)) + + StoreDefinesSection(DecFile, DefinesTupleList) + + +## Return a Package Include Class Item. +# +# Read the input Include class object and return one Include Class Item. +# +# @param Include An input Include class object. +# +# @retval IncludeClassItem A Package Include Class Item. +# +def GetPackageIncludeClassItem(Include): + return Include.FilePath + + +## Store Includes section. +# +# Write [Includes] section to the DecFile based on Package class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param DecFile The output DEC file to store the Includes section. +# @param Package An input Package class object. +# +def StorePackageIncludesSection(DecFile, Package): + Includes = Package.Includes + Section = GetSection("Includes", GetPackageIncludeClassItem, Includes) + StoreTextFile(DecFile, Section) + + +## Return a Package Library Class Item. +# +# Read the input LibraryClass class object and return one Library Class Item. +# +# @param LibraryClass An input LibraryClass class object. +# +# @retval LibraryClassItem A Package Library Class Item. +# +def GetPackageLibraryClassItem(LibraryClass): + return "|".join((LibraryClass.LibraryClass, LibraryClass.IncludeHeader)) + + +## Store Library Classes section. +# +# Write [LibraryClasses] section to the DecFile based on Package class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param DecFile The output DEC file to store the Library Classes +# section. +# @param Package An input Package class object. +# +def StorePackageLibraryClassesSection(DecFile, Package): + LibraryClasses = Package.LibraryClassDeclarations + Section = GetSection("LibraryClasses", GetPackageLibraryClassItem, LibraryClasses) + StoreTextFile(DecFile, Section) + + +## Return a Package Guid Declaration Item. +# +# Read the input Guid class object and return one line of Guid Declaration Item. +# +# @param Guid An input Guid class object. +# +# @retval GuidDeclarationItem A Package Guid Declaration Item. +# +def GetPackageGuidDeclarationItem(Guid): + GuidCName = Guid.CName + GuidValue = Guid.Guid.replace("-", "") + GuidValueList = [GuidValue[0:8]] + GuidValueList += [GuidValue[i : i + 4] for i in range(8, 16, 4)] + GuidValueList += [GuidValue[i : i + 2] for i in range(16, 32, 2)] + + GuidCFormat = "{0x%s" + ", 0x%s" * 2 + ", {0x%s" + ", 0x%s" * 7 + "}}" + GuidCValue = GuidCFormat % tuple(GuidValueList) + return "%-30s = %s" % (GuidCName, GuidCValue) + + +## Store Protocols section. +# +# Write [Protocols] section to the DecFile based on Package class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param DecFile The output DEC file to store the Protocols section. +# @param Package An input Package class object. +# +def StorePackageProtocolsSection(DecFile, Package): + Protocols = Package.ProtocolDeclarations + Section = GetSection("Protocols", GetPackageGuidDeclarationItem, Protocols) + StoreTextFile(DecFile, Section) + + +## Store Ppis section. +# +# Write [Ppis] section to the DecFile based on Package class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param DecFile The output DEC file to store the Ppis section. +# @param Package An input Package class object. +# +def StorePackagePpisSection(DecFile, Package): + Ppis = Package.PpiDeclarations + Section = GetSection("Ppis", GetPackageGuidDeclarationItem, Ppis) + StoreTextFile(DecFile, Section) + + +## Store Guids section. +# +# Write [Guids] section to the DecFile based on Package class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param DecFile The output DEC file to store the Guids section. +# @param Package An input Package class object. +# +def StorePackageGuidsSection(DecFile, Package): + Guids = Package.GuidDeclarations + Section = GetSection("Guids", GetPackageGuidDeclarationItem, Guids) + StoreTextFile(DecFile, Section) + + +## Return a Package Pcd Item. +# +# Read the input Pcd class object and return one line of Pcd Item. +# +# @param Pcd An input Pcd class object. +# +# @retval PcdItem A Package Pcd Item. +# +def GetPackagePcdItem(Pcd): + PcdPair = "%s.%s" % (Pcd.TokenSpaceGuidCName, Pcd.CName) + DatumType = Pcd.DatumType + DefaultValue = Pcd.DefaultValue + Token = Pcd.Token + PcdList = [PcdPair, DefaultValue, DatumType, Token] + return "|".join(PcdList) + + +## DEC Pcd Section Name dictionary indexed by PCD Item Type. +mDecPcdSectionNameDict = { + "FEATURE_FLAG" : "PcdsFeatureFlag", + "FIXED_AT_BUILD" : "PcdsFixedAtBuild", + "PATCHABLE_IN_MODULE" : "PcdsPatchableInModule", + "DYNAMIC" : "PcdsDynamic", + "DYNAMIC_EX" : "PcdsDynamicEx" + } + +## Store Pcds section. +# +# Write [Pcds*] section to the DecFile based on Package class object. +# Different CPU architectures are specified in the subsection if possible. +# +# @param DecFile The output DEC file to store the Pcds section. +# @param Package An input Package class object. +# +def StorePackagePcdsSection(DecFile, Package): + PcdsDict = {} + for Pcd in Package.PcdDeclarations: + for PcdItemType in Pcd.ValidUsage: + PcdSectionName = mDecPcdSectionNameDict.get(PcdItemType) + if PcdSectionName: + PcdsDict.setdefault(PcdSectionName, []).append(Pcd) + else: + EdkLogger.info("Unknown Pcd Item Type: %s" % PcdItemType) + + Section = "" + for PcdSectionName in PcdsDict: + Pcds = PcdsDict[PcdSectionName] + Section += GetSection(PcdSectionName, GetPackagePcdItem, Pcds) + + StoreTextFile(DecFile, Section) + + +## Store User Extensions section. +# +# Write [UserExtensions] section to the DecFile based on Package class object. +# +# @param DecFile The output DEC file to store the User Extensions section. +# @param Package An input Package class object. +# +def StorePackageUserExtensionsSection(DecFile, Package): + Section = "".join(map(GetUserExtensions, Package.UserExtensions)) + StoreTextFile(DecFile, Section) + + +## Store a Package class object to a new DEC file. +# +# Read an input Package class object and ave the contents to a new DEC file. +# +# @param DecFileName The output DEC file. +# @param Package An input Package class object. +# +def StoreDec(DecFileName, Package): + DecFile = open(DecFileName, "w+") + EdkLogger.info("Save file to %s" % DecFileName) + + StoreHeader(DecFile, Package.Header) + StorePackageDefinesSection(DecFile, Package) + StorePackageIncludesSection(DecFile, Package) + StorePackageLibraryClassesSection(DecFile, Package) + StorePackageProtocolsSection(DecFile, Package) + StorePackagePpisSection(DecFile, Package) + StorePackageGuidsSection(DecFile, Package) + StorePackagePcdsSection(DecFile, Package) + StorePackageUserExtensionsSection(DecFile, Package) + + DecFile.close() + + +# This acts like the main() function for the script, unless it is 'import'ed +# into another script. +if __name__ == '__main__': + pass + \ No newline at end of file diff --git a/BaseTools/Source/Python/spd2dec/__init__.py b/BaseTools/Source/Python/spd2dec/__init__.py new file mode 100644 index 0000000000..e69de29bb2 -- cgit v1.2.3