1## @file
2# This file is used to define class objects of INF file [Packages] section.
3# It will consumed by InfParser.
4#
5# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
6#
7# This program and the accompanying materials are licensed and made available
8# under the terms and conditions of the BSD License which accompanies this
9# distribution. The full text of the license may be found at
10# http://opensource.org/licenses/bsd-license.php
11#
12# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15'''
16InfPackageObject
17'''
18
19from Logger import StringTable as ST
20from Logger import ToolError
21import Logger.Log as Logger
22from Library import GlobalData
23
24from Library.Misc import Sdict
25from Library.ParserValidate import IsValidPath
26from Library.ExpressionValidate import IsValidFeatureFlagExp
27
28class InfPackageItem():
29    def __init__(self,
30                 PackageName = '',
31                 FeatureFlagExp = '',
32                 HelpString = ''):
33        self.PackageName    = PackageName
34        self.FeatureFlagExp = FeatureFlagExp
35        self.HelpString     = HelpString
36        self.SupArchList    = []
37
38    def SetPackageName(self, PackageName):
39        self.PackageName = PackageName
40    def GetPackageName(self):
41        return self.PackageName
42
43    def SetFeatureFlagExp(self, FeatureFlagExp):
44        self.FeatureFlagExp = FeatureFlagExp
45    def GetFeatureFlagExp(self):
46        return self.FeatureFlagExp
47
48    def SetHelpString(self, HelpString):
49        self.HelpString = HelpString
50    def GetHelpString(self):
51        return self.HelpString
52
53    def SetSupArchList(self, SupArchList):
54        self.SupArchList = SupArchList
55    def GetSupArchList(self):
56        return self.SupArchList
57
58
59## INF package section
60#
61#
62#
63class InfPackageObject():
64    def __init__(self):
65        self.Packages = Sdict()
66        #
67        # Macro defined in this section should be only used in this section.
68        #
69        self.Macros         = {}
70
71    def SetPackages(self, PackageData, Arch = None):
72        IsValidFileFlag = False
73        SupArchList     = []
74        for ArchItem in Arch:
75            #
76            # Validate Arch
77            #
78            if (ArchItem == '' or ArchItem == None):
79                ArchItem = 'COMMON'
80            SupArchList.append(ArchItem)
81
82        for PackageItem in PackageData:
83            PackageItemObj = InfPackageItem()
84            HelpStringObj = PackageItem[1]
85            CurrentLineOfPackItem = PackageItem[2]
86            PackageItem = PackageItem[0]
87            if HelpStringObj != None:
88                HelpString = HelpStringObj.HeaderComments + HelpStringObj.TailComments
89                PackageItemObj.SetHelpString(HelpString)
90            if len(PackageItem) >= 1:
91                #
92                # Validate file exist/format.
93                #
94                if IsValidPath(PackageItem[0], ''):
95                    IsValidFileFlag = True
96                elif IsValidPath(PackageItem[0], GlobalData.gINF_MODULE_DIR):
97                    IsValidFileFlag = True
98                elif IsValidPath(PackageItem[0], GlobalData.gWORKSPACE):
99                    IsValidFileFlag = True
100                else:
101                    Logger.Error("InfParser",
102                                 ToolError.FORMAT_INVALID,
103                                 ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID%(PackageItem[0]),
104                                 File=CurrentLineOfPackItem[2],
105                                 Line=CurrentLineOfPackItem[1],
106                                 ExtraData=CurrentLineOfPackItem[0])
107                    return False
108                if IsValidFileFlag:
109                    PackageItemObj.SetPackageName(PackageItem[0])
110            if len(PackageItem) == 2:
111                #
112                # Validate Feature Flag Express
113                #
114                if PackageItem[1].strip() == '':
115                    Logger.Error("InfParser",
116                                 ToolError.FORMAT_INVALID,
117                                 ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING,
118                                 File=CurrentLineOfPackItem[2],
119                                 Line=CurrentLineOfPackItem[1],
120                                 ExtraData=CurrentLineOfPackItem[0])
121                #
122                # Validate FFE
123                #
124                FeatureFlagRtv = IsValidFeatureFlagExp(PackageItem[1].strip())
125                if not FeatureFlagRtv[0]:
126                    Logger.Error("InfParser",
127                                 ToolError.FORMAT_INVALID,
128                                 ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%(FeatureFlagRtv[1]),
129                                 File=CurrentLineOfPackItem[2],
130                                 Line=CurrentLineOfPackItem[1],
131                                 ExtraData=CurrentLineOfPackItem[0])
132
133                PackageItemObj.SetFeatureFlagExp(PackageItem[1].strip())
134
135            if len(PackageItem) > 2:
136                #
137                # Invalid format of Package statement
138                #
139                Logger.Error("InfParser",
140                             ToolError.FORMAT_INVALID,
141                             ST.ERR_INF_PARSER_PACKAGE_SECTION_CONTENT_ERROR,
142                             File=CurrentLineOfPackItem[2],
143                             Line=CurrentLineOfPackItem[1],
144                             ExtraData=CurrentLineOfPackItem[0])
145            PackageItemObj.SetSupArchList(SupArchList)
146
147            #
148            # Determine package file name duplicate. Follow below rule:
149            #
150            # A package filename must not be duplicated within a [Packages]
151            # section. Package filenames may appear in multiple architectural
152            # [Packages] sections. A package filename listed in an
153            # architectural [Packages] section must not be listed in the common
154            # architectural [Packages] section.
155            #
156            # NOTE: This check will not report error now.
157            #
158            for Item in self.Packages:
159                if Item.GetPackageName() == PackageItemObj.GetPackageName():
160                    ItemSupArchList = Item.GetSupArchList()
161                    for ItemArch in ItemSupArchList:
162                        for PackageItemObjArch in SupArchList:
163                            if ItemArch == PackageItemObjArch:
164                                #
165                                # ST.ERR_INF_PARSER_ITEM_DUPLICATE
166                                #
167                                pass
168                            if ItemArch.upper() == 'COMMON' or PackageItemObjArch.upper() == 'COMMON':
169                                #
170                                # ST.ERR_INF_PARSER_ITEM_DUPLICATE_COMMON
171                                #
172                                pass
173
174            if self.Packages.has_key((PackageItemObj)):
175                PackageList = self.Packages[PackageItemObj]
176                PackageList.append(PackageItemObj)
177                self.Packages[PackageItemObj] = PackageList
178            else:
179                PackageList = []
180                PackageList.append(PackageItemObj)
181                self.Packages[PackageItemObj] = PackageList
182
183        return True
184
185    def GetPackages(self, Arch = None):
186        if Arch == None:
187            return self.Packages