• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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