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