1## @file 2# This file is used to provide method for process AsBuilt INF file. It will consumed by InfParser 3# 4# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR> 5# 6# SPDX-License-Identifier: BSD-2-Clause-Patent 7''' 8InfAsBuiltProcess 9''' 10## Import modules 11# 12 13import os 14import re 15from Library import GlobalData 16import Logger.Log as Logger 17from Logger import StringTable as ST 18from Logger import ToolError 19 20from Library.StringUtils import GetSplitValueList 21from Library.Misc import GetHelpStringByRemoveHashKey 22from Library.Misc import ValidFile 23from Library.Misc import ProcessLineExtender 24from Library.ParserValidate import IsValidPath 25from Library.Parsing import MacroParser 26from Parser.InfParserMisc import InfExpandMacro 27 28from Library import DataType as DT 29 30## GetLibInstanceInfo 31# 32# Get the information from Library Instance INF file. 33# 34# @param string. A string start with # and followed by INF file path 35# @param WorkSpace. The WorkSpace directory used to combined with INF file path. 36# 37# @return GUID, Version 38def GetLibInstanceInfo(String, WorkSpace, LineNo, CurrentInfFileName): 39 40 FileGuidString = "" 41 VerString = "" 42 43 OriginalString = String 44 String = String.strip() 45 if not String: 46 return None, None 47 # 48 # Remove "#" characters at the beginning 49 # 50 String = GetHelpStringByRemoveHashKey(String) 51 String = String.strip() 52 53 # 54 # To deal with library instance specified by GUID and version 55 # 56 RegFormatGuidPattern = re.compile("\s*([0-9a-fA-F]){8}-" 57 "([0-9a-fA-F]){4}-" 58 "([0-9a-fA-F]){4}-" 59 "([0-9a-fA-F]){4}-" 60 "([0-9a-fA-F]){12}\s*") 61 VersionPattern = re.compile('[\t\s]*\d+(\.\d+)?[\t\s]*') 62 GuidMatchedObj = RegFormatGuidPattern.search(String) 63 64 if String.upper().startswith('GUID') and GuidMatchedObj and 'Version' in String: 65 VersionStr = String[String.upper().find('VERSION') + 8:] 66 VersionMatchedObj = VersionPattern.search(VersionStr) 67 if VersionMatchedObj: 68 Guid = GuidMatchedObj.group().strip() 69 Version = VersionMatchedObj.group().strip() 70 return Guid, Version 71 72 # 73 # To deal with library instance specified by file name 74 # 75 FileLinesList = GetFileLineContent(String, WorkSpace, LineNo, OriginalString) 76 77 78 ReFindFileGuidPattern = re.compile("^\s*FILE_GUID\s*=.*$") 79 ReFindVerStringPattern = re.compile("^\s*VERSION_STRING\s*=.*$") 80 81 for Line in FileLinesList: 82 if ReFindFileGuidPattern.match(Line): 83 FileGuidString = Line 84 if ReFindVerStringPattern.match(Line): 85 VerString = Line 86 87 if FileGuidString: 88 FileGuidString = GetSplitValueList(FileGuidString, '=', 1)[1] 89 if VerString: 90 VerString = GetSplitValueList(VerString, '=', 1)[1] 91 92 return FileGuidString, VerString 93 94## GetPackageListInfo 95# 96# Get the package information from INF file. 97# 98# @param string. A string start with # and followed by INF file path 99# @param WorkSpace. The WorkSpace directory used to combined with INF file path. 100# 101# @return GUID, Version 102def GetPackageListInfo(FileNameString, WorkSpace, LineNo): 103 PackageInfoList = [] 104 DefineSectionMacros = {} 105 PackageSectionMacros = {} 106 107 FileLinesList = GetFileLineContent(FileNameString, WorkSpace, LineNo, '') 108 109 RePackageHeader = re.compile('^\s*\[Packages.*\].*$') 110 ReDefineHeader = re.compile('^\s*\[Defines].*$') 111 112 PackageHederFlag = False 113 DefineHeaderFlag = False 114 LineNo = -1 115 for Line in FileLinesList: 116 LineNo += 1 117 Line = Line.strip() 118 119 if Line.startswith('['): 120 PackageHederFlag = False 121 DefineHeaderFlag = False 122 123 if Line.startswith("#"): 124 continue 125 126 if not Line: 127 continue 128 129 # 130 # Found [Packages] section 131 # 132 if RePackageHeader.match(Line): 133 PackageHederFlag = True 134 continue 135 136 # 137 # Found [Define] section 138 # 139 if ReDefineHeader.match(Line): 140 DefineHeaderFlag = True 141 continue 142 143 if DefineHeaderFlag: 144 # 145 # Find Macro 146 # 147 Name, Value = MacroParser((Line, LineNo), 148 FileNameString, 149 DT.MODEL_META_DATA_HEADER, 150 DefineSectionMacros) 151 152 if Name is not None: 153 DefineSectionMacros[Name] = Value 154 continue 155 156 if PackageHederFlag: 157 158 # 159 # Find Macro 160 # 161 Name, Value = MacroParser((Line, LineNo), 162 FileNameString, 163 DT.MODEL_META_DATA_PACKAGE, 164 DefineSectionMacros) 165 if Name is not None: 166 PackageSectionMacros[Name] = Value 167 continue 168 169 # 170 # Replace with Local section Macro and [Defines] section Macro. 171 # 172 Line = InfExpandMacro(Line, (FileNameString, Line, LineNo), DefineSectionMacros, PackageSectionMacros, True) 173 174 Line = GetSplitValueList(Line, "#", 1)[0] 175 Line = GetSplitValueList(Line, "|", 1)[0] 176 PackageInfoList.append(Line) 177 178 return PackageInfoList 179 180def GetFileLineContent(FileName, WorkSpace, LineNo, OriginalString): 181 182 if not LineNo: 183 LineNo = -1 184 185 # 186 # Validate file name exist. 187 # 188 FullFileName = os.path.normpath(os.path.realpath(os.path.join(WorkSpace, FileName))) 189 if not (ValidFile(FullFileName)): 190 return [] 191 192 # 193 # Validate file exist/format. 194 # 195 if not IsValidPath(FileName, WorkSpace): 196 return [] 197 198 FileLinesList = [] 199 200 try: 201 FullFileName = FullFileName.replace('\\', '/') 202 Inputfile = open(FullFileName, "r") 203 try: 204 FileLinesList = Inputfile.readlines() 205 except BaseException: 206 Logger.Error("InfParser", ToolError.FILE_READ_FAILURE, ST.ERR_FILE_OPEN_FAILURE, File=FullFileName) 207 finally: 208 Inputfile.close() 209 except BaseException: 210 Logger.Error("InfParser", 211 ToolError.FILE_READ_FAILURE, 212 ST.ERR_FILE_OPEN_FAILURE, 213 File=FullFileName) 214 215 FileLinesList = ProcessLineExtender(FileLinesList) 216 217 return FileLinesList 218 219## 220# Get all INF files from current workspace 221# 222# 223def GetInfsFromWorkSpace(WorkSpace): 224 InfFiles = [] 225 for top, dirs, files in os.walk(WorkSpace): 226 dirs = dirs # just for pylint 227 for File in files: 228 if File.upper().endswith(".INF"): 229 InfFiles.append(os.path.join(top, File)) 230 231 return InfFiles 232 233## 234# Get GUID and version from library instance file 235# 236# 237def GetGuidVerFormLibInstance(Guid, Version, WorkSpace, CurrentInfFileName): 238 for InfFile in GetInfsFromWorkSpace(WorkSpace): 239 try: 240 if InfFile.strip().upper() == CurrentInfFileName.strip().upper(): 241 continue 242 InfFile = InfFile.replace('\\', '/') 243 if InfFile not in GlobalData.gLIBINSTANCEDICT: 244 InfFileObj = open(InfFile, "r") 245 GlobalData.gLIBINSTANCEDICT[InfFile] = InfFileObj 246 else: 247 InfFileObj = GlobalData.gLIBINSTANCEDICT[InfFile] 248 249 except BaseException: 250 Logger.Error("InfParser", 251 ToolError.FILE_READ_FAILURE, 252 ST.ERR_FILE_OPEN_FAILURE, 253 File=InfFile) 254 try: 255 FileLinesList = InfFileObj.readlines() 256 FileLinesList = ProcessLineExtender(FileLinesList) 257 258 ReFindFileGuidPattern = re.compile("^\s*FILE_GUID\s*=.*$") 259 ReFindVerStringPattern = re.compile("^\s*VERSION_STRING\s*=.*$") 260 261 for Line in FileLinesList: 262 if ReFindFileGuidPattern.match(Line): 263 FileGuidString = Line 264 if ReFindVerStringPattern.match(Line): 265 VerString = Line 266 267 if FileGuidString: 268 FileGuidString = GetSplitValueList(FileGuidString, '=', 1)[1] 269 if VerString: 270 VerString = GetSplitValueList(VerString, '=', 1)[1] 271 272 if FileGuidString.strip().upper() == Guid.upper() and \ 273 VerString.strip().upper() == Version.upper(): 274 return Guid, Version 275 276 except BaseException: 277 Logger.Error("InfParser", ToolError.FILE_READ_FAILURE, ST.ERR_FILE_OPEN_FAILURE, File=InfFile) 278 finally: 279 InfFileObj.close() 280 281 return '', '' 282 283 284