1. Add check point for invalid library instance, package, component file name
[people/mcb30/basetools.git] / Source / Python / Common / DecClassObject.py
1 # Copyright (c) 2007, Intel Corporation\r
2 # All rights reserved. This program and the accompanying materials\r
3 # are licensed and made available under the terms and conditions of the BSD License\r
4 # which accompanies this distribution.    The full text of the license may be found at\r
5 # http://opensource.org/licenses/bsd-license.php\r
6 #\r
7 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
8 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
9 \r
10 #\r
11 #This file is used to define each component of DEC file\r
12 #\r
13 \r
14 import os\r
15 from String import *\r
16 from DataType import *\r
17 from Identification import *\r
18 from Dictionary import *\r
19 from CommonDataClass.PackageClass import *\r
20 from BuildToolError import *\r
21 \r
22 class DecObject(object):\r
23     def __init__(self):\r
24         object.__init__()\r
25 \r
26 class DecDefines(DecObject):\r
27     def __init__(self):\r
28         self.DefinesDictionary = {\r
29             #Req\r
30             TAB_DEC_DEFINES_DEC_SPECIFICATION           : [''],\r
31             TAB_DEC_DEFINES_PACKAGE_NAME                : [''],\r
32             TAB_DEC_DEFINES_PACKAGE_GUID                : [''],\r
33             TAB_DEC_DEFINES_PACKAGE_VERSION             : ['']\r
34         }\r
35         \r
36 class DecContents(DecObject):\r
37     def __init__(self):\r
38         self.Includes = []\r
39         self.Guids = []\r
40         self.Protocols = []\r
41         self.Ppis = []\r
42         self.LibraryClasses = []\r
43         self.PcdsFixedAtBuild = []\r
44         self.PcdsPatchableInModule = []\r
45         self.PcdsFeatureFlag = []\r
46         self.PcdsDynamic = []\r
47         self.PcdsDynamicEx = []\r
48 \r
49 class Dec(DecObject):\r
50     def __init__(self, filename = None, isMergeAllArches = False, isToPackage = False):\r
51         self.Identification = Identification()\r
52         self.Defines = DecDefines()\r
53         self.UserExtensions = ''\r
54         self.Package = PackageClass()\r
55         \r
56         self.Contents = {}\r
57         for key in DataType.ARCH_LIST_FULL:\r
58             self.Contents[key] = DecContents()\r
59         \r
60         self.KeyList = [\r
61             TAB_INCLUDES, TAB_GUIDS, TAB_PROTOCOLS, TAB_PPIS, TAB_LIBRARY_CLASSES, \\r
62             TAB_PCDS_FIXED_AT_BUILD_NULL, TAB_PCDS_PATCHABLE_IN_MODULE_NULL, TAB_PCDS_FEATURE_FLAG_NULL, \\r
63             TAB_PCDS_DYNAMIC_NULL, TAB_PCDS_DYNAMIC_EX_NULL\r
64         ]\r
65     \r
66         if filename != None:\r
67             self.LoadDecFile(filename)\r
68             \r
69         if isMergeAllArches:\r
70             self.MergeAllArches()\r
71         \r
72         if isToPackage:\r
73             self.DecToPackage()\r
74     \r
75     def ParseDec(self, Lines, Key, KeyField):\r
76         newKey = SplitModuleType(Key)\r
77         if newKey[0].find(DataType.TAB_LIBRARY_CLASSES.upper()) != -1:\r
78             GetLibraryClassesWithModuleType(Lines, Key, KeyField, TAB_COMMENT_SPLIT)\r
79         else:\r
80             GetMultipleValuesOfKeyFromLines(Lines, Key, KeyField, TAB_COMMENT_SPLIT)\r
81             \r
82     def MergeAllArches(self):\r
83         for key in self.KeyList:\r
84             for arch in DataType.ARCH_LIST:\r
85                 Command = "self.Contents[arch]." + key + ".extend(" + "self.Contents['" + DataType.TAB_ARCH_COMMON + "']." + key + ")"\r
86                 eval(Command)\r
87 \r
88     def LoadDecFile(self, Filename):\r
89         (Filepath, Name) = os.path.split(Filename)\r
90         self.Identification.FileName = Name\r
91         self.Identification.FileFullPath = Filename\r
92         self.Identification.FileRelativePath = Filepath\r
93         \r
94         f = open(Filename, 'r').read()\r
95         PreCheck(Filename, f, self.KeyList)\r
96         sects = f.split('[')\r
97         for sect in sects:\r
98             tab = (sect.split(TAB_SECTION_END, 1)[0]).upper()\r
99             if tab == TAB_INF_DEFINES.upper():\r
100                 GetSingleValueOfKeyFromLines(sect, self.Defines.DefinesDictionary, TAB_COMMENT_SPLIT, TAB_EQUAL_SPLIT, True, TAB_VALUE_SPLIT)\r
101                 continue\r
102             for arch in DataType.ARCH_LIST_FULL + [DataType.TAB_ARCH_NULL]:\r
103                 for key in self.KeyList:\r
104                     if arch != DataType.TAB_ARCH_NULL:\r
105                         target = (key + DataType.TAB_SPLIT + arch).upper()\r
106                     else:\r
107                         target = key.upper()\r
108                     if tab == target:\r
109                         if arch != DataType.TAB_ARCH_NULL:\r
110                             Command = 'self.ParseDec(sect, tab, self.Contents[arch].' + key + ')'\r
111                             eval(Command)\r
112                             continue\r
113                         else:\r
114                             Command = "self.ParseDec(sect, tab, self.Contents['" + DataType.TAB_ARCH_COMMON + "']." + key + ')'\r
115                             eval(Command)\r
116                             continue\r
117         #EndFor\r
118 \r
119     def DecToPackage(self):\r
120         #\r
121         # Get value for Header\r
122         #\r
123         self.Package.Header.Name = self.Defines.DefinesDictionary[TAB_DEC_DEFINES_PACKAGE_NAME][0]\r
124         self.Package.Header.Guid = self.Defines.DefinesDictionary[TAB_DEC_DEFINES_PACKAGE_GUID][0]\r
125         self.Package.Header.Version = self.Defines.DefinesDictionary[TAB_DEC_DEFINES_PACKAGE_VERSION][0]\r
126         self.Package.Header.FileName = self.Identification.FileName\r
127         self.Package.Header.FullPath = self.Identification.FileFullPath\r
128         self.Package.Header.DecSpecification = self.Defines.DefinesDictionary[TAB_DEC_DEFINES_DEC_SPECIFICATION][0]\r
129         \r
130         #Includes\r
131         Includes = {}\r
132         for Arch in DataType.ARCH_LIST:\r
133             for Item in self.Contents[Arch].Includes:\r
134                 MergeArches(Includes, Item, Arch)\r
135         for Key in Includes.keys():\r
136             Include = IncludeClass()\r
137             Include.FilePath = Key\r
138             Include.SupArchList = Includes[Key]\r
139             self.Package.Includes.append(Include)\r
140             \r
141         #Guids\r
142         Guids = {}\r
143         for Arch in DataType.ARCH_LIST:\r
144             for Item in self.Contents[Arch].Guids:\r
145                 List = GetSplitValueList(Item, DataType.TAB_EQUAL_SPLIT)\r
146                 if len(List) != 2:\r
147                     ErrorMsg = "Wrong statement '%s' found in section Guids in file '%s', correct format is '<CName>=<GuidValue>'" % (Item, self.Package.Header.FullPath) \r
148                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
149                 else:\r
150                     MergeArches(Guids, (List[0], List[1]), Arch)\r
151         for Key in Guids.keys():\r
152             Guid = GuidClass()\r
153             Guid.CName = Key[0]\r
154             Guid.Guid = Key[1]\r
155             Guid.SupArchList = Guids[Key]\r
156             self.Package.GuidDeclarations.append(Guid)\r
157 \r
158         #Protocols\r
159         Protocols = {}\r
160         for Arch in DataType.ARCH_LIST:\r
161             for Item in self.Contents[Arch].Protocols:\r
162                 List = GetSplitValueList(Item, DataType.TAB_EQUAL_SPLIT)\r
163                 if len(List) != 2:\r
164                     ErrorMsg = "Wrong statement '%s' found in section Protocols in file '%s', correct format is '<CName>=<GuidValue>'" % (Item, self.Package.Header.FullPath) \r
165                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
166                 else:\r
167                     MergeArches(Protocols, (List[0], List[1]), Arch)\r
168         for Key in Protocols.keys():\r
169             Protocol = ProtocolClass()\r
170             Protocol.CName = Key[0]\r
171             Protocol.Guid = Key[1]\r
172             Protocol.SupArchList = Protocols[Key]\r
173             self.Package.ProtocolDeclarations.append(Protocol)\r
174         \r
175         #Ppis\r
176         Ppis = {}\r
177         for Arch in DataType.ARCH_LIST:\r
178             for Item in self.Contents[Arch].Ppis:\r
179                 List = GetSplitValueList(Item, DataType.TAB_EQUAL_SPLIT)\r
180                 if len(List) != 2:\r
181                     ErrorMsg = "Wrong statement '%s' found in section Ppis in file '%s', correct format is '<CName>=<GuidValue>'" % (Item, self.Package.Header.FullPath) \r
182                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
183                 else:\r
184                     MergeArches(Ppis, (List[0], List[1]), Arch)\r
185         for Key in Ppis.keys():\r
186             Ppi = PpiClass()\r
187             Ppi.CName = Key[0]\r
188             Ppi.Guid = Key[1]\r
189             Ppi.SupArchList = Ppis[Key]\r
190             self.Package.PpiDeclarations.append(Ppi)\r
191             \r
192         #LibraryClasses\r
193         LibraryClasses = {}\r
194         for Arch in DataType.ARCH_LIST:\r
195             for Item in self.Contents[Arch].LibraryClasses:\r
196                 List = GetSplitValueList(Item[0], DataType.TAB_VALUE_SPLIT)\r
197                 if len(List) != 2:\r
198                     ErrorMsg = "Wrong statement '%s' found in section LibraryClasses in file '%s', correct format is '<CName>=<GuidValue>'" % (Item, self.Package.Header.FullPath) \r
199                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
200                 else:\r
201 #                    if List[1] != '' and CheckFileType(List[1], '.Inf') == False:\r
202 #                        ErrorMsg = "Wrong library instance '%s' found for LibraryClasses '%s' in file '%s', it is NOT a valid INF file" % (List[1], List[0], self.Package.Header.FullPath) \r
203 #                        raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
204                     if Item[1] == ['']:\r
205                             Item[1] = DataType.SUP_MODULE_LIST\r
206                     MergeArches(LibraryClasses, (List[0], List[1]) + tuple(Item[1]), Arch)\r
207         for Key in LibraryClasses.keys():\r
208             LibraryClass = LibraryClassClass()\r
209             LibraryClass.LibraryClass = Key[0]\r
210             LibraryClass.RecommendedInstance = Key[1]\r
211             LibraryClass.SupModuleList = list(Key[2:])\r
212             LibraryClass.SupArchList = LibraryClasses[Key]\r
213             self.Package.LibraryClassDeclarations.append(LibraryClass)\r
214         \r
215         #Pcds\r
216         Pcds = {}\r
217         for Arch in DataType.ARCH_LIST:\r
218             for Item in self.Contents[Arch].PcdsFixedAtBuild:\r
219                 List = GetSplitValueList(Item)\r
220                 if len(List) != 5:\r
221                     ErrorMsg = "Wrong statement '%s' found in section PcdsFixedAtBuild in file '%s', correct format is '<TokenCName>|<Token>|<CName>|<DatumType>|<Default>'" % (Item, self.Package.Header.FullPath) \r
222                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
223                 MergeArches(Pcds, (List[0], List[1], List[2], List[3], List[4],TAB_PCDS_FIXED_AT_BUILD), Arch)\r
224             for Item in self.Contents[Arch].PcdsPatchableInModule:\r
225                 List = GetSplitValueList(Item)\r
226                 if len(List) != 5:\r
227                     ErrorMsg = "Wrong statement '%s' found in section PcdsPatchableInModule in file '%s', correct format is '<TokenCName>|<Token>|<CName>|<DatumType>|<Default>'" % (Item, self.Package.Header.FullPath) \r
228                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
229                 MergeArches(Pcds, (List[0], List[1], List[2], List[3], List[4], TAB_PCDS_PATCHABLE_IN_MODULE), Arch)\r
230             for Item in self.Contents[Arch].PcdsFeatureFlag:\r
231                 List = GetSplitValueList(Item)\r
232                 if len(List) != 5:\r
233                     ErrorMsg = "Wrong statement '%s' found in section PcdsFeatureFlag in file '%s', correct format is '<TokenCName>|<Token>|<CName>|<DatumType>|<Default>'" % (Item, self.Package.Header.FullPath) \r
234                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
235                 MergeArches(Pcds, (List[0], List[1], List[2], List[3], List[4], TAB_PCDS_FEATURE_FLAG), Arch)\r
236             for Item in self.Contents[Arch].PcdsDynamicEx:\r
237                 List = GetSplitValueList(Item)\r
238                 if len(List) != 5:\r
239                     ErrorMsg = "Wrong statement '%s' found in section PcdsDynamicEx in file '%s', correct format is '<TokenCName>|<Token>|<CName>|<DatumType>|<Default>'" % (Item, self.Package.Header.FullPath) \r
240                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
241                 MergeArches(Pcds, (List[0], List[1], List[2], List[3], List[4], TAB_PCDS_DYNAMIC_EX), Arch)\r
242             for Item in self.Contents[Arch].PcdsDynamic:\r
243                 List = GetSplitValueList(Item)\r
244                 if len(List) != 5:\r
245                     ErrorMsg = "Wrong statement '%s' found in section PcdsDynamic in file '%s', correct format is '<TokenCName>|<Token>|<CName>|<DatumType>|<Default>'" % (Item, self.Package.Header.FullPath) \r
246                     raise ParserError(PARSER_ERROR, msg = ErrorMsg)\r
247                 MergeArches(Pcds, (List[0], List[1], List[2], List[3], List[4], TAB_PCDS_DYNAMIC), Arch)\r
248         for Key in Pcds.keys():\r
249             Pcd = PcdClass()\r
250             Pcd.CName = Key[0]\r
251             Pcd.Token = Key[1]\r
252             Pcd.TokenSpaceGuidCName = Key[2]\r
253             Pcd.DatumType = Key[3]\r
254             Pcd.DefaultValue = Key[4]\r
255             Pcd.ItemType = Key[5]\r
256             Pcd.SupArchList = Pcds[Key]\r
257             self.Package.PcdDeclarations.append(Pcd)\r
258     \r
259     def ShowDec(self):\r
260         print TAB_SECTION_START + TAB_INF_DEFINES + TAB_SECTION_END\r
261         printDict(self.Defines.DefinesDictionary)\r
262 \r
263         for key in self.KeyList:\r
264             for arch in DataType.ARCH_LIST_FULL:\r
265                 Command = "printList(TAB_SECTION_START + '" + \\r
266                                     key + DataType.TAB_SPLIT + arch + \\r
267                                     "' + TAB_SECTION_END, self.Contents[arch]." + key + ')'\r
268                 eval(Command)\r
269     \r
270     def ShowPackage(self):\r
271         m = self.Package\r
272         print 'Filename =', m.Header.FileName\r
273         print 'FullPath =', m.Header.FullPath\r
274         print 'BaseName =', m.Header.Name\r
275         print 'Guid =', m.Header.Guid\r
276         print 'Version =', m.Header.Version\r
277         print 'DecSpecification =', m.Header.DecSpecification\r
278         print '\nIncludes =', m.Includes\r
279         for Item in m.Includes:\r
280             print Item.FilePath, Item.SupArchList\r
281         print '\nGuids =', m.GuidDeclarations\r
282         for Item in m.GuidDeclarations:\r
283             print Item.CName, Item.Guid, Item.SupArchList\r
284         print '\nProtocols =', m.ProtocolDeclarations\r
285         for Item in m.ProtocolDeclarations:\r
286             print Item.CName, Item.Guid, Item.SupArchList\r
287         print '\nPpis =', m.PpiDeclarations\r
288         for Item in m.PpiDeclarations:\r
289             print Item.CName, Item.Guid, Item.SupArchList\r
290         print '\nLibraryClasses =', m.LibraryClassDeclarations\r
291         for Item in m.LibraryClassDeclarations:\r
292             print Item.LibraryClass, Item.RecommendedInstance, Item.SupModuleList, Item.SupArchList\r
293         print '\nPcds =', m.PcdDeclarations\r
294         for Item in m.PcdDeclarations:\r
295             print Item.CName, Item.TokenSpaceGuidCName, Item.DefaultValue, Item.ItemType, Item.Token, Item.DatumType, Item.SupArchList\r
296 \r
297 if __name__ == '__main__':\r
298     p = Dec()\r
299     directory = 'C:\Documents and Settings\\hchen30\\Desktop\\prototype\\dec'\r
300     fileList = []\r
301     for f in os.listdir(directory):\r
302         if os.path.splitext(os.path.normcase(f))[1] == '.dec':\r
303             fileList.append(os.path.join(directory, os.path.normcase(f)))\r
304             \r
305     for f in fileList:\r
306         p = Dec(f, True, True)\r
307         #p.ShowDec()\r
308         p.ShowPackage()\r