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