## @file\r
-# This file is used to define common parsing related functions used in parsing \r
+# This file is used to define common parsing related functions used in parsing\r
# INF/DEC/DSC process\r
#\r
-# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
#\r
-# This program and the accompanying materials are licensed and made available \r
-# under the terms and conditions of the BSD License which accompanies this \r
-# distribution. The full text of the license may be found at \r
+# This program and the accompanying materials are licensed and made available\r
+# under the terms and conditions of the BSD License which accompanies this\r
+# distribution. The full text of the license may be found at\r
# http://opensource.org/licenses/bsd-license.php\r
#\r
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
'''\r
Parsing\r
'''\r
+from __future__ import absolute_import\r
\r
##\r
# Import Modules\r
import os.path\r
import re\r
\r
-from Library.String import RaiseParserError\r
-from Library.String import GetSplitValueList\r
-from Library.String import CheckFileType\r
-from Library.String import CheckFileExist\r
-from Library.String import CleanString\r
-from Library.String import NormPath\r
+from Library.StringUtils import RaiseParserError\r
+from Library.StringUtils import GetSplitValueList\r
+from Library.StringUtils import CheckFileType\r
+from Library.StringUtils import CheckFileExist\r
+from Library.StringUtils import CleanString\r
+from Library.StringUtils import NormPath\r
\r
from Logger.ToolError import FILE_NOT_FOUND\r
from Logger.ToolError import FatalError\r
import Logger.Log as Logger\r
\r
from Parser.DecParser import Dec\r
+from . import GlobalData\r
\r
gPKG_INFO_DICT = {}\r
\r
# @param String: String with BuildOption statement\r
# @param File: The file which defines build option, used in error report\r
#\r
-def GetBuildOption(String, File, LineNo=-1):\r
+def GetBuildOption(String, File, LineNo= -1):\r
(Family, ToolChain, Flag) = ('', '', '')\r
if String.find(DataType.TAB_EQUAL_SPLIT) < 0:\r
RaiseParserError(String, 'BuildOptions', File, \\r
# Get Library of Dsc as <LibraryClassKeyWord>|<LibraryInstance>\r
#\r
# @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>\r
-# @param ContainerFile: The file which describes the library class, used for \r
+# @param ContainerFile: The file which describes the library class, used for\r
# error report\r
#\r
-def GetLibraryClass(Item, ContainerFile, WorkspaceDir, LineNo=-1):\r
+def GetLibraryClass(Item, ContainerFile, WorkspaceDir, LineNo= -1):\r
List = GetSplitValueList(Item[0])\r
SupMod = DataType.SUP_MODULE_LIST_STRING\r
if len(List) != 2:\r
# [|<TokenSpaceGuidCName>.<PcdCName>]\r
#\r
# @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>\r
-# @param ContainerFile: The file which describes the library class, used for \r
+# @param ContainerFile: The file which describes the library class, used for\r
# error report\r
#\r
-def GetLibraryClassOfInf(Item, ContainerFile, WorkspaceDir, LineNo = -1):\r
+def GetLibraryClassOfInf(Item, ContainerFile, WorkspaceDir, LineNo= -1):\r
ItemList = GetSplitValueList((Item[0] + DataType.TAB_VALUE_SPLIT * 2))\r
SupMod = DataType.SUP_MODULE_LIST_STRING\r
\r
# @param Section: Used for error report\r
# @param File: Used for error report\r
#\r
-def CheckPcdTokenInfo(TokenInfoString, Section, File, LineNo=-1):\r
+def CheckPcdTokenInfo(TokenInfoString, Section, File, LineNo= -1):\r
Format = '<TokenSpaceGuidCName>.<PcdCName>'\r
- if TokenInfoString != '' and TokenInfoString != None:\r
+ if TokenInfoString != '' and TokenInfoString is not None:\r
TokenInfoList = GetSplitValueList(TokenInfoString, DataType.TAB_SPLIT)\r
if len(TokenInfoList) == 2:\r
return True\r
#\r
# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|\r
# <Value>[|<Type>|<MaximumDatumSize>]\r
-# @param ContainerFile: The file which describes the pcd, used for error \r
+# @param ContainerFile: The file which describes the pcd, used for error\r
# report\r
\r
#\r
-def GetPcd(Item, Type, ContainerFile, LineNo=-1):\r
+def GetPcd(Item, Type, ContainerFile, LineNo= -1):\r
TokenGuid, TokenName, Value, MaximumDatumSize, Token = '', '', '', '', ''\r
List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT * 2)\r
\r
#\r
# @param Item: String as <PcdTokenSpaceGuidCName>\r
# .<TokenCName>|TRUE/FALSE\r
-# @param ContainerFile: The file which describes the pcd, used for error \r
+# @param ContainerFile: The file which describes the pcd, used for error\r
# report\r
#\r
-def GetFeatureFlagPcd(Item, Type, ContainerFile, LineNo=-1):\r
+def GetFeatureFlagPcd(Item, Type, ContainerFile, LineNo= -1):\r
TokenGuid, TokenName, Value = '', '', ''\r
List = GetSplitValueList(Item)\r
if len(List) != 2:\r
#\r
# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|\r
# TRUE/FALSE\r
-# @param ContainerFile: The file which describes the pcd, used for error \r
+# @param ContainerFile: The file which describes the pcd, used for error\r
# report\r
#\r
-def GetDynamicDefaultPcd(Item, Type, ContainerFile, LineNo=-1):\r
+def GetDynamicDefaultPcd(Item, Type, ContainerFile, LineNo= -1):\r
TokenGuid, TokenName, Value, DatumTyp, MaxDatumSize = '', '', '', '', ''\r
List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT * 2)\r
if len(List) < 4 or len(List) > 8:\r
#\r
# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|\r
# TRUE/FALSE\r
-# @param ContainerFile: The file which describes the pcd, used for error \r
+# @param ContainerFile: The file which describes the pcd, used for error\r
# report\r
#\r
-def GetDynamicHiiPcd(Item, Type, ContainerFile, LineNo = -1):\r
+def GetDynamicHiiPcd(Item, Type, ContainerFile, LineNo= -1):\r
TokenGuid, TokenName, List1, List2, List3, List4, List5 = \\r
'', '', '', '', '', '', ''\r
List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT * 2)\r
#\r
# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>\r
# |TRUE/FALSE\r
-# @param ContainerFile: The file which describes the pcd, used for error \r
+# @param ContainerFile: The file which describes the pcd, used for error\r
# report\r
#\r
-def GetDynamicVpdPcd(Item, Type, ContainerFile, LineNo=-1):\r
+def GetDynamicVpdPcd(Item, Type, ContainerFile, LineNo= -1):\r
TokenGuid, TokenName, List1, List2 = '', '', '', ''\r
List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT)\r
if len(List) < 3 or len(List) > 4:\r
## GetComponent\r
#\r
# Parse block of the components defined in dsc file\r
-# Set KeyValues as [ ['component name', [lib1, lib2, lib3], \r
+# Set KeyValues as [ ['component name', [lib1, lib2, lib3],\r
# [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...]\r
#\r
# @param Lines: The content to be parsed\r
## GetComponents\r
#\r
# Parse block of the components defined in dsc file\r
-# Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3], \r
+# Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3],\r
# [pcd1, pcd2, pcd3]], ...]\r
#\r
# @param Lines: The content to be parsed\r
LineList = Lines.split('\n')\r
for Line in LineList:\r
Line = CleanString(Line, CommentCharacter)\r
- if Line == None or Line == '':\r
+ if Line is None or Line == '':\r
continue\r
\r
if FindBlock == False:\r
#\r
# @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>\r
# [|<PcdFeatureFlag>]]]]\r
-# @param ContainerFile: The file which describes the library class, used \r
+# @param ContainerFile: The file which describes the library class, used\r
# for error report\r
#\r
-def GetSource(Item, ContainerFile, FileRelativePath, LineNo=-1):\r
+def GetSource(Item, ContainerFile, FileRelativePath, LineNo= -1):\r
ItemNew = Item + DataType.TAB_VALUE_SPLIT * 4\r
List = GetSplitValueList(ItemNew)\r
if len(List) < 5 or len(List) > 9:\r
#\r
# @param Item: String as <Filename>[|<Family>[|<TagName>\r
# [|<ToolCode>[|<PcdFeatureFlag>]]]]\r
-# @param ContainerFile: The file which describes the library class, \r
+# @param ContainerFile: The file which describes the library class,\r
# used for error report\r
#\r
-def GetBinary(Item, ContainerFile, LineNo=-1):\r
+def GetBinary(Item, ContainerFile, LineNo= -1):\r
ItemNew = Item + DataType.TAB_VALUE_SPLIT\r
List = GetSplitValueList(ItemNew)\r
if len(List) < 3 or len(List) > 5:\r
#\r
# @param Item: String as <GuidCName>[|<PcdFeatureFlag>]\r
# @param Type: Type of parsing string\r
-# @param ContainerFile: The file which describes the library class, \r
+# @param ContainerFile: The file which describes the library class,\r
# used for error report\r
#\r
def GetGuidsProtocolsPpisOfInf(Item):\r
#\r
# @param Item: String as <GuidCName>=<GuidValue>\r
# @param Type: Type of parsing string\r
-# @param ContainerFile: The file which describes the library class, \r
+# @param ContainerFile: The file which describes the library class,\r
# used for error report\r
#\r
-def GetGuidsProtocolsPpisOfDec(Item, Type, ContainerFile, LineNo=-1):\r
+def GetGuidsProtocolsPpisOfDec(Item, Type, ContainerFile, LineNo= -1):\r
List = GetSplitValueList(Item, DataType.TAB_EQUAL_SPLIT)\r
if len(List) != 2:\r
RaiseParserError(Item, Type, ContainerFile, '<CName>=<GuidValue>', \\r
RegisterFormatGuid = List[1]\r
else:\r
RaiseParserError(Item, Type, ContainerFile, \\r
- 'CFormat or RegisterFormat', LineNo) \r
+ 'CFormat or RegisterFormat', LineNo)\r
\r
return (List[0], RegisterFormatGuid)\r
\r
#\r
# @param Item: String as <PackagePath>[|<PcdFeatureFlag>]\r
# @param Type: Type of parsing string\r
-# @param ContainerFile: The file which describes the library class, \r
+# @param ContainerFile: The file which describes the library class,\r
# used for error report\r
#\r
-def GetPackage(Item, ContainerFile, FileRelativePath, LineNo=-1):\r
+def GetPackage(Item, ContainerFile, FileRelativePath, LineNo= -1):\r
ItemNew = Item + DataType.TAB_VALUE_SPLIT\r
List = GetSplitValueList(ItemNew)\r
CheckFileType(List[0], '.Dec', ContainerFile, 'package', List[0], LineNo)\r
# @param File: Dec file\r
# @param LineNo: Line number\r
#\r
-def GetPcdOfDec(Item, Type, File, LineNo=-1):\r
+def GetPcdOfDec(Item, Type, File, LineNo= -1):\r
Format = '<TokenSpaceGuidCName>.<PcdCName>|<Value>|<DatumType>|<Token>'\r
TokenGuid, TokenName, Value, DatumType, Token = '', '', '', '', ''\r
List = GetSplitValueList(Item)\r
LineValue, StartLine, Comment = SectionItem[0], \\r
SectionItem[1], SectionItem[2]\r
\r
- Logger.Debug(4, ST.MSG_PARSING %LineValue)\r
+ Logger.Debug(4, ST.MSG_PARSING % LineValue)\r
#\r
# And then parse DEFINE statement\r
#\r
List[Key] = [Value]\r
else:\r
List[Key].append(Value)\r
- \r
+\r
## GetPkgInfoFromDec\r
#\r
# get package name, guid, version info from dec files\r
PkgName = None\r
PkgGuid = None\r
PkgVersion = None\r
- \r
+\r
Path = Path.replace('\\', '/')\r
- \r
+\r
if not os.path.exists(Path):\r
- Logger.Error("\nUPT", FILE_NOT_FOUND, File = Path) \r
+ Logger.Error("\nUPT", FILE_NOT_FOUND, File=Path)\r
\r
if Path in gPKG_INFO_DICT:\r
return gPKG_INFO_DICT[Path]\r
\r
try:\r
- DecParser = Dec(Path)\r
+ DecParser = None\r
+ if Path not in GlobalData.gPackageDict:\r
+ DecParser = Dec(Path)\r
+ GlobalData.gPackageDict[Path] = DecParser\r
+ else:\r
+ DecParser = GlobalData.gPackageDict[Path]\r
+\r
PkgName = DecParser.GetPackageName()\r
PkgGuid = DecParser.GetPackageGuid()\r
PkgVersion = DecParser.GetPackageVersion()\r
#\r
def GetWorkspacePackage():\r
DecFileList = []\r
- WorkspaceDir = os.environ["WORKSPACE"]\r
- for Root, Dirs, Files in os.walk(WorkspaceDir):\r
- if 'CVS' in Dirs:\r
- Dirs.remove('CVS')\r
- if '.svn' in Dirs:\r
- Dirs.remove('.svn')\r
- for Dir in Dirs:\r
- if Dir.startswith('.'):\r
- Dirs.remove(Dir)\r
- for FileSp in Files:\r
- if FileSp.startswith('.'):\r
- continue\r
- Ext = os.path.splitext(FileSp)[1]\r
- if Ext.lower() in ['.dec']:\r
- DecFileList.append\\r
- (os.path.normpath(os.path.join(Root, FileSp)))\r
+ WorkspaceDir = GlobalData.gWORKSPACE\r
+ PackageDir = GlobalData.gPACKAGE_PATH\r
+ for PkgRoot in [WorkspaceDir] + PackageDir:\r
+ for Root, Dirs, Files in os.walk(PkgRoot):\r
+ if 'CVS' in Dirs:\r
+ Dirs.remove('CVS')\r
+ if '.svn' in Dirs:\r
+ Dirs.remove('.svn')\r
+ for Dir in Dirs:\r
+ if Dir.startswith('.'):\r
+ Dirs.remove(Dir)\r
+ for FileSp in Files:\r
+ if FileSp.startswith('.'):\r
+ continue\r
+ Ext = os.path.splitext(FileSp)[1]\r
+ if Ext.lower() in ['.dec']:\r
+ DecFileList.append\\r
+ (os.path.normpath(os.path.join(Root, FileSp)))\r
#\r
# abstract package guid, version info from DecFile List\r
#\r
(PkgName, PkgGuid, PkgVersion) = GetPkgInfoFromDec(DecFile)\r
if PkgName and PkgGuid and PkgVersion:\r
PkgList.append((PkgName, PkgGuid, PkgVersion, DecFile))\r
- \r
+\r
return PkgList\r
\r
## GetWorkspaceModule\r
#\r
def GetWorkspaceModule():\r
InfFileList = []\r
- WorkspaceDir = os.environ["WORKSPACE"]\r
+ WorkspaceDir = GlobalData.gWORKSPACE\r
for Root, Dirs, Files in os.walk(WorkspaceDir):\r
if 'CVS' in Dirs:\r
Dirs.remove('CVS')\r
if Ext.lower() in ['.inf']:\r
InfFileList.append\\r
(os.path.normpath(os.path.join(Root, FileSp)))\r
- \r
+\r
return InfFileList\r
\r
## MacroParser used to parse macro definition\r
# Not 'DEFINE/EDK_GLOBAL' statement, call decorated method\r
#\r
return None, None\r
- \r
+\r
TokenList = GetSplitValueList(LineContent[Match.end(1):], \\r
DataType.TAB_EQUAL_SPLIT, 1)\r
#\r
#\r
if SectionType == DataType.MODEL_META_DATA_HEADER:\r
FileLocalMacros[Name] = Value\r
- \r
+\r
ReIsValidMacroName = re.compile(r"^[A-Z][A-Z0-9_]*$", re.DOTALL)\r
- if ReIsValidMacroName.match(Name) == None:\r
- Logger.Error('Parser', \r
- FORMAT_INVALID, \r
- ST.ERR_MACRONAME_INVALID%(Name),\r
- ExtraData=LineContent, \r
- File=FileName, \r
+ if ReIsValidMacroName.match(Name) is None:\r
+ Logger.Error('Parser',\r
+ FORMAT_INVALID,\r
+ ST.ERR_MACRONAME_INVALID % (Name),\r
+ ExtraData=LineContent,\r
+ File=FileName,\r
Line=LineNo)\r
- \r
+\r
# Validate MACRO Value\r
#\r
# <MacroDefinition> ::= [<Comments>]{0,}\r
# <Value> ::= {<NumVal>} {<Boolean>} {<AsciiString>} {<GUID>}\r
# {<CString>} {<UnicodeString>} {<CArray>}\r
#\r
- # The definition of <NumVal>, <PATH>, <Boolean>, <GUID>, <CString>, \r
+ # The definition of <NumVal>, <PATH>, <Boolean>, <GUID>, <CString>,\r
# <UnicodeString>, <CArray> are subset of <AsciiString>.\r
#\r
ReIsValidMacroValue = re.compile(r"^[\x20-\x7e]*$", re.DOTALL)\r
- if ReIsValidMacroValue.match(Value) == None:\r
- Logger.Error('Parser', \r
- FORMAT_INVALID, \r
- ST.ERR_MACROVALUE_INVALID%(Value),\r
- ExtraData=LineContent, \r
- File=FileName, \r
+ if ReIsValidMacroValue.match(Value) is None:\r
+ Logger.Error('Parser',\r
+ FORMAT_INVALID,\r
+ ST.ERR_MACROVALUE_INVALID % (Value),\r
+ ExtraData=LineContent,\r
+ File=FileName,\r
Line=LineNo)\r
- \r
+\r
return Name, Value\r
\r
-## GenSection \r
+## GenSection\r
#\r
# generate section contents\r
#\r
-# @param SectionName: indicate the name of the section, details refer to \r
+# @param SectionName: indicate the name of the section, details refer to\r
# INF, DEC specs\r
-# @param SectionDict: section statement dict, key is SectionAttrs(arch, \r
-# moduletype or platform may exist as needed) list \r
-# seperated by space, \r
+# @param SectionDict: section statement dict, key is SectionAttrs(arch,\r
+# moduletype or platform may exist as needed) list\r
+# seperated by space,\r
# value is statement\r
#\r
-def GenSection(SectionName, SectionDict, SplitArch=True):\r
+def GenSection(SectionName, SectionDict, SplitArch=True, NeedBlankLine=False):\r
Content = ''\r
for SectionAttrs in SectionDict:\r
StatementList = SectionDict[SectionAttrs]\r
Section = '[' + SectionName + '.' + (', ' + SectionName + '.').join(ArchList) + ']'\r
else:\r
Section = '[' + SectionName + ']'\r
- Content += '\n\n' + Section + '\n'\r
- if StatementList != None:\r
+ Content += '\n' + Section + '\n'\r
+ if StatementList is not None:\r
for Statement in StatementList:\r
- Content += Statement + '\n'\r
+ LineList = Statement.split('\n')\r
+ NewStatement = ""\r
+ for Line in LineList:\r
+ # ignore blank comment\r
+ if not Line.replace("#", '').strip() and SectionName not in ('Defines', 'Hob', 'Event', 'BootMode'):\r
+ continue\r
+ # add two space before non-comments line except the comments in Defines section\r
+ if Line.strip().startswith('#') and SectionName == 'Defines':\r
+ NewStatement += "%s\n" % Line\r
+ continue\r
+ NewStatement += " %s\n" % Line\r
+ if NeedBlankLine:\r
+ Content += NewStatement + '\n'\r
+ else:\r
+ Content += NewStatement\r
\r
+ if NeedBlankLine:\r
+ Content = Content[:-1]\r
+ if not Content.replace('\\n', '').strip():\r
+ return ''\r
return Content\r
\r
## ConvertArchForInstall\r
-# if Arch.upper() is in "IA32", "X64", "IPF", and "EBC", it must be upper case. "common" must be lower case. \r
+# if Arch.upper() is in "IA32", "X64", "IPF", and "EBC", it must be upper case. "common" must be lower case.\r
# Anything else, the case must be preserved\r
#\r
-# @param Arch: the arch string that need to be converted, it should be stripped before pass in \r
+# @param Arch: the arch string that need to be converted, it should be stripped before pass in\r
# @return: the arch string that get converted\r
#\r
def ConvertArchForInstall(Arch):\r
- if Arch.upper() in [DataType.TAB_ARCH_IA32, DataType.TAB_ARCH_X64, \r
+ if Arch.upper() in [DataType.TAB_ARCH_IA32, DataType.TAB_ARCH_X64,\r
DataType.TAB_ARCH_IPF, DataType.TAB_ARCH_EBC]:\r
Arch = Arch.upper()\r
elif Arch.upper() == DataType.TAB_ARCH_COMMON:\r
Arch = Arch.lower()\r
- \r
+\r
return Arch\r