1## @file 2# This file is used to collect all defined strings in Image Definition files 3# 4# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> 5# This program and the accompanying materials 6# are licensed and made available under the terms and conditions of the BSD License 7# which accompanies this distribution. The full text of the license may be found at 8# http://opensource.org/licenses/bsd-license.php 9# 10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13## 14# Import Modules 15# 16import Common.EdkLogger as EdkLogger 17import StringIO 18from Common.BuildToolError import * 19from Common.String import GetLineNo 20from Common.Misc import PathClass 21from Common.LongFilePathSupport import LongFilePath 22import re 23import os 24 25IMAGE_TOKEN = re.compile('IMAGE_TOKEN *\(([A-Z0-9_]+) *\)', re.MULTILINE | re.UNICODE) 26 27# 28# Value of different image information block types 29# 30EFI_HII_IIBT_END = 0x00 31EFI_HII_IIBT_IMAGE_1BIT = 0x10 32EFI_HII_IIBT_IMAGE_1BIT_TRANS = 0x11 33EFI_HII_IIBT_IMAGE_4BIT = 0x12 34EFI_HII_IIBT_IMAGE_4BIT_TRANS = 0x13 35EFI_HII_IIBT_IMAGE_8BIT = 0x14 36EFI_HII_IIBT_IMAGE_8BIT_TRANS = 0x15 37EFI_HII_IIBT_IMAGE_24BIT = 0x16 38EFI_HII_IIBT_IMAGE_24BIT_TRANS = 0x17 39EFI_HII_IIBT_IMAGE_JPEG = 0x18 40EFI_HII_IIBT_IMAGE_PNG = 0x19 41EFI_HII_IIBT_DUPLICATE = 0x20 42EFI_HII_IIBT_SKIP2 = 0x21 43EFI_HII_IIBT_SKIP1 = 0x22 44EFI_HII_IIBT_EXT1 = 0x30 45EFI_HII_IIBT_EXT2 = 0x31 46EFI_HII_IIBT_EXT4 = 0x32 47 48# 49# Value of HII package type 50# 51EFI_HII_PACKAGE_TYPE_ALL = 0x00 52EFI_HII_PACKAGE_TYPE_GUID = 0x01 53EFI_HII_PACKAGE_FORMS = 0x02 54EFI_HII_PACKAGE_STRINGS = 0x04 55EFI_HII_PACKAGE_FONTS = 0x05 56EFI_HII_PACKAGE_IMAGES = 0x06 57EFI_HII_PACKAGE_SIMPLE_FONTS = 0x07 58EFI_HII_PACKAGE_DEVICE_PATH = 0x08 59EFI_HII_PACKAGE_KEYBOARD_LAYOUT = 0x09 60EFI_HII_PACKAGE_ANIMATIONS = 0x0A 61EFI_HII_PACKAGE_END = 0xDF 62EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN = 0xE0 63EFI_HII_PACKAGE_TYPE_SYSTEM_END = 0xFF 64 65class IdfFileClassObject(object): 66 def __init__(self, FileList = []): 67 self.FileList = FileList 68 self.ImageFilesDict = {} 69 self.ImageIDList = [] 70 if len(self.FileList) > 0: 71 self.LoadIdfFiles(FileList) 72 73 def LoadIdfFiles(self, FileList): 74 if len(FileList) > 0: 75 for File in FileList: 76 self.LoadIdfFile(File) 77 78 def LoadIdfFile(self, File = None): 79 if File == None: 80 EdkLogger.error("Image Definition File Parser", PARSER_ERROR, 'No Image definition file is given.') 81 self.File = File 82 83 try: 84 IdfFile = open(LongFilePath(File.Path), mode='r') 85 FileIn = IdfFile.read() 86 IdfFile.close() 87 except: 88 EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=File) 89 90 ImageFileList = [] 91 for Line in FileIn.splitlines(): 92 Line = Line.strip() 93 Line = self.StripComments(Line) 94 if len(Line) == 0: 95 continue 96 97 LineNo = GetLineNo(FileIn, Line, False) 98 if not Line.startswith('#image '): 99 EdkLogger.error("Image Definition File Parser", PARSER_ERROR, 'The %s in Line %s of File %s is invalid.' % (Line, LineNo, File.Path)) 100 101 if Line.find('#image ') >= 0: 102 LineDetails = Line.split() 103 Len = len(LineDetails) 104 if Len != 3 and Len != 4: 105 EdkLogger.error("Image Definition File Parser", PARSER_ERROR, 'The format is not match #image IMAGE_ID [TRANSPARENT] ImageFileName in Line %s of File %s.' % (LineNo, File.Path)) 106 if Len == 4 and LineDetails[2] != 'TRANSPARENT': 107 EdkLogger.error("Image Definition File Parser", PARSER_ERROR, 'Please use the keyword "TRANSPARENT" to describe the transparency setting in Line %s of File %s.' % (LineNo, File.Path)) 108 MatchString = re.match('^[a-zA-Z][a-zA-Z0-9_]*$', LineDetails[1], re.UNICODE) 109 if MatchString == None or MatchString.end(0) != len(LineDetails[1]): 110 EdkLogger.error('Image Definition File Parser', FORMAT_INVALID, 'The Image token name %s defined in Idf file %s contains the invalid character.' % (LineDetails[1], File.Path)) 111 if LineDetails[1] not in self.ImageIDList: 112 self.ImageIDList.append(LineDetails[1]) 113 else: 114 EdkLogger.error("Image Definition File Parser", PARSER_ERROR, 'The %s in Line %s of File %s is already defined.' % (LineDetails[1], LineNo, File.Path)) 115 if Len == 4: 116 ImageFile = ImageFileObject(LineDetails[Len-1], LineDetails[1], True) 117 else: 118 ImageFile = ImageFileObject(LineDetails[Len-1], LineDetails[1], False) 119 ImageFileList.append(ImageFile) 120 if ImageFileList: 121 self.ImageFilesDict[File] = ImageFileList 122 123 def StripComments(self, Line): 124 Comment = '//' 125 CommentPos = Line.find(Comment) 126 while CommentPos >= 0: 127 # if there are non matched quotes before the comment header 128 # then we are in the middle of a string 129 # but we need to ignore the escaped quotes and backslashes. 130 if ((Line.count('"', 0, CommentPos) - Line.count('\\"', 0, CommentPos)) & 1) == 1: 131 CommentPos = Line.find (Comment, CommentPos + 1) 132 else: 133 return Line[:CommentPos].strip() 134 return Line.strip() 135 136 def ImageDecoder(self, File): 137 pass 138 139def SearchImageID(ImageFileObject, FileList): 140 if FileList == []: 141 return ImageFileObject 142 143 for File in FileList: 144 if os.path.isfile(File): 145 Lines = open(File, 'r') 146 for Line in Lines: 147 ImageIdList = IMAGE_TOKEN.findall(Line) 148 for ID in ImageIdList: 149 EdkLogger.debug(EdkLogger.DEBUG_5, "Found ImageID identifier: " + ID) 150 ImageFileObject.SetImageIDReferenced(ID) 151 152class ImageFileObject(object): 153 def __init__(self, FileName, ImageID, TransParent = False): 154 self.FileName = FileName 155 self.File = '' 156 self.ImageID = ImageID 157 self.TransParent = TransParent 158 self.Referenced = False 159 160 def SetImageIDReferenced(self, ImageID): 161 if ImageID == self.ImageID: 162 self.Referenced = True 163