]>
Commit | Line | Data |
---|---|---|
ae7b6df8 LG |
1 | ## @file\r |
2 | # This file is used to create a database used by build tool\r | |
3 | #\r | |
e0db09cd | 4 | # Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>\r |
ae7b6df8 LG |
5 | # (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r |
6 | # This program and the accompanying materials\r | |
7 | # are licensed and made available under the terms and conditions of the BSD License\r | |
8 | # which accompanies this distribution. The full text of the license may be found at\r | |
9 | # http://opensource.org/licenses/bsd-license.php\r | |
10 | #\r | |
11 | # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
12 | # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
13 | #\r | |
5a57246e | 14 | from Common.StringUtils import *\r |
ae7b6df8 LG |
15 | from Common.DataType import *\r |
16 | from Common.Misc import *\r | |
17 | from types import *\r | |
79820e32 | 18 | from collections import OrderedDict\r |
938cf4c3 | 19 | from CommonDataClass.DataClass import *\r |
ae7b6df8 | 20 | from Workspace.BuildClassObject import PackageBuildClassObject, StructurePcd, PcdClassObject\r |
938cf4c3 CJ |
21 | from Common.GlobalData import gGlobalDefines, gEcpSource\r |
22 | from re import compile\r | |
ae7b6df8 LG |
23 | \r |
24 | ## Platform build information from DEC file\r | |
25 | #\r | |
26 | # This class is used to retrieve information stored in database and convert them\r | |
27 | # into PackageBuildClassObject form for easier use for AutoGen.\r | |
28 | #\r | |
29 | class DecBuildData(PackageBuildClassObject):\r | |
30 | # dict used to convert PCD type in database to string used by build tool\r | |
31 | _PCD_TYPE_STRING_ = {\r | |
be409b67 CJ |
32 | MODEL_PCD_FIXED_AT_BUILD : TAB_PCDS_FIXED_AT_BUILD,\r |
33 | MODEL_PCD_PATCHABLE_IN_MODULE : TAB_PCDS_PATCHABLE_IN_MODULE,\r | |
34 | MODEL_PCD_FEATURE_FLAG : TAB_PCDS_FEATURE_FLAG,\r | |
35 | MODEL_PCD_DYNAMIC : TAB_PCDS_DYNAMIC,\r | |
36 | MODEL_PCD_DYNAMIC_DEFAULT : TAB_PCDS_DYNAMIC,\r | |
37 | MODEL_PCD_DYNAMIC_HII : TAB_PCDS_DYNAMIC_HII,\r | |
38 | MODEL_PCD_DYNAMIC_VPD : TAB_PCDS_DYNAMIC_VPD,\r | |
39 | MODEL_PCD_DYNAMIC_EX : TAB_PCDS_DYNAMIC_EX,\r | |
40 | MODEL_PCD_DYNAMIC_EX_DEFAULT : TAB_PCDS_DYNAMIC_EX,\r | |
41 | MODEL_PCD_DYNAMIC_EX_HII : TAB_PCDS_DYNAMIC_EX_HII,\r | |
42 | MODEL_PCD_DYNAMIC_EX_VPD : TAB_PCDS_DYNAMIC_EX_VPD,\r | |
ae7b6df8 LG |
43 | }\r |
44 | \r | |
45 | # dict used to convert part of [Defines] to members of DecBuildData directly\r | |
46 | _PROPERTY_ = {\r | |
47 | #\r | |
48 | # Required Fields\r | |
49 | #\r | |
50 | TAB_DEC_DEFINES_PACKAGE_NAME : "_PackageName",\r | |
51 | TAB_DEC_DEFINES_PACKAGE_GUID : "_Guid",\r | |
52 | TAB_DEC_DEFINES_PACKAGE_VERSION : "_Version",\r | |
53 | TAB_DEC_DEFINES_PKG_UNI_FILE : "_PkgUniFile",\r | |
54 | }\r | |
55 | \r | |
56 | \r | |
57 | ## Constructor of DecBuildData\r | |
58 | #\r | |
59 | # Initialize object of DecBuildData\r | |
60 | #\r | |
61 | # @param FilePath The path of package description file\r | |
62 | # @param RawData The raw data of DEC file\r | |
63 | # @param BuildDataBase Database used to retrieve module information\r | |
64 | # @param Arch The target architecture\r | |
65 | # @param Platform (not used for DecBuildData)\r | |
66 | # @param Macros Macros used for replacement in DSC file\r | |
67 | #\r | |
55c84777 | 68 | def __init__(self, File, RawData, BuildDataBase, Arch=TAB_ARCH_COMMON, Target=None, Toolchain=None):\r |
ae7b6df8 LG |
69 | self.MetaFile = File\r |
70 | self._PackageDir = File.Dir\r | |
71 | self._RawData = RawData\r | |
72 | self._Bdb = BuildDataBase\r | |
73 | self._Arch = Arch\r | |
74 | self._Target = Target\r | |
75 | self._Toolchain = Toolchain\r | |
76 | self._Clear()\r | |
77 | \r | |
78 | ## XXX[key] = value\r | |
79 | def __setitem__(self, key, value):\r | |
80 | self.__dict__[self._PROPERTY_[key]] = value\r | |
81 | \r | |
82 | ## value = XXX[key]\r | |
83 | def __getitem__(self, key):\r | |
84 | return self.__dict__[self._PROPERTY_[key]]\r | |
85 | \r | |
86 | ## "in" test support\r | |
87 | def __contains__(self, key):\r | |
88 | return key in self._PROPERTY_\r | |
89 | \r | |
90 | ## Set all internal used members of DecBuildData to None\r | |
91 | def _Clear(self):\r | |
92 | self._Header = None\r | |
93 | self._PackageName = None\r | |
94 | self._Guid = None\r | |
95 | self._Version = None\r | |
96 | self._PkgUniFile = None\r | |
97 | self._Protocols = None\r | |
98 | self._Ppis = None\r | |
99 | self._Guids = None\r | |
100 | self._Includes = None\r | |
0a57a978 | 101 | self._CommonIncludes = None\r |
ae7b6df8 LG |
102 | self._LibraryClasses = None\r |
103 | self._Pcds = None\r | |
71cac3f7 | 104 | self._MacroDict = None\r |
ae7b6df8 LG |
105 | self._PrivateProtocols = None\r |
106 | self._PrivatePpis = None\r | |
107 | self._PrivateGuids = None\r | |
108 | self._PrivateIncludes = None\r | |
109 | \r | |
110 | ## Get current effective macros\r | |
71cac3f7 CJ |
111 | @property\r |
112 | def _Macros(self):\r | |
113 | if self._MacroDict is None:\r | |
938cf4c3 | 114 | self._MacroDict = dict(gGlobalDefines)\r |
71cac3f7 | 115 | return self._MacroDict\r |
ae7b6df8 LG |
116 | \r |
117 | ## Get architecture\r | |
71cac3f7 CJ |
118 | @property\r |
119 | def Arch(self):\r | |
ae7b6df8 LG |
120 | return self._Arch\r |
121 | \r | |
ae7b6df8 LG |
122 | ## Retrieve all information in [Defines] section\r |
123 | #\r | |
124 | # (Retriving all [Defines] information in one-shot is just to save time.)\r | |
125 | #\r | |
126 | def _GetHeaderInfo(self):\r | |
127 | RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]\r | |
128 | for Record in RecordList:\r | |
129 | Name = Record[1]\r | |
130 | if Name in self:\r | |
131 | self[Name] = Record[2]\r | |
132 | self._Header = 'DUMMY'\r | |
133 | \r | |
134 | ## Retrieve package name\r | |
71cac3f7 CJ |
135 | @property\r |
136 | def PackageName(self):\r | |
4231a819 CJ |
137 | if self._PackageName is None:\r |
138 | if self._Header is None:\r | |
ae7b6df8 | 139 | self._GetHeaderInfo()\r |
4231a819 | 140 | if self._PackageName is None:\r |
ae7b6df8 LG |
141 | EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_NAME", File=self.MetaFile)\r |
142 | return self._PackageName\r | |
143 | \r | |
144 | ## Retrieve file guid\r | |
71cac3f7 CJ |
145 | @property\r |
146 | def PackageName(self):\r | |
4231a819 CJ |
147 | if self._Guid is None:\r |
148 | if self._Header is None:\r | |
ae7b6df8 | 149 | self._GetHeaderInfo()\r |
4231a819 | 150 | if self._Guid is None:\r |
ae7b6df8 LG |
151 | EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_GUID", File=self.MetaFile)\r |
152 | return self._Guid\r | |
153 | \r | |
154 | ## Retrieve package version\r | |
71cac3f7 CJ |
155 | @property\r |
156 | def Version(self):\r | |
4231a819 CJ |
157 | if self._Version is None:\r |
158 | if self._Header is None:\r | |
ae7b6df8 | 159 | self._GetHeaderInfo()\r |
4231a819 | 160 | if self._Version is None:\r |
ae7b6df8 LG |
161 | self._Version = ''\r |
162 | return self._Version\r | |
163 | \r | |
164 | ## Retrieve protocol definitions (name/value pairs)\r | |
71cac3f7 CJ |
165 | @property\r |
166 | def Protocols(self):\r | |
4231a819 | 167 | if self._Protocols is None:\r |
ae7b6df8 LG |
168 | #\r |
169 | # tdict is a special kind of dict, used for selecting correct\r | |
170 | # protocol defition for given ARCH\r | |
171 | #\r | |
172 | ProtocolDict = tdict(True)\r | |
173 | PrivateProtocolDict = tdict(True)\r | |
174 | NameList = []\r | |
175 | PrivateNameList = []\r | |
176 | PublicNameList = []\r | |
177 | # find out all protocol definitions for specific and 'common' arch\r | |
178 | RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch]\r | |
179 | for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:\r | |
180 | if PrivateFlag == 'PRIVATE':\r | |
181 | if Name not in PrivateNameList:\r | |
182 | PrivateNameList.append(Name)\r | |
183 | PrivateProtocolDict[Arch, Name] = Guid\r | |
184 | if Name in PublicNameList:\r | |
185 | EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)\r | |
186 | else:\r | |
187 | if Name not in PublicNameList:\r | |
188 | PublicNameList.append(Name)\r | |
189 | if Name in PrivateNameList:\r | |
190 | EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)\r | |
191 | if Name not in NameList:\r | |
192 | NameList.append(Name)\r | |
193 | ProtocolDict[Arch, Name] = Guid\r | |
6e6d767e CJ |
194 | # use OrderedDict to keep the order\r |
195 | self._Protocols = OrderedDict()\r | |
196 | self._PrivateProtocols = OrderedDict()\r | |
ae7b6df8 LG |
197 | for Name in NameList:\r |
198 | #\r | |
199 | # limit the ARCH to self._Arch, if no self._Arch found, tdict\r | |
200 | # will automatically turn to 'common' ARCH for trying\r | |
201 | #\r | |
202 | self._Protocols[Name] = ProtocolDict[self._Arch, Name]\r | |
203 | for Name in PrivateNameList:\r | |
204 | self._PrivateProtocols[Name] = PrivateProtocolDict[self._Arch, Name]\r | |
205 | return self._Protocols\r | |
206 | \r | |
207 | ## Retrieve PPI definitions (name/value pairs)\r | |
71cac3f7 CJ |
208 | @property\r |
209 | def Ppis(self):\r | |
4231a819 | 210 | if self._Ppis is None:\r |
ae7b6df8 LG |
211 | #\r |
212 | # tdict is a special kind of dict, used for selecting correct\r | |
213 | # PPI defition for given ARCH\r | |
214 | #\r | |
215 | PpiDict = tdict(True)\r | |
216 | PrivatePpiDict = tdict(True)\r | |
217 | NameList = []\r | |
218 | PrivateNameList = []\r | |
219 | PublicNameList = []\r | |
220 | # find out all PPI definitions for specific arch and 'common' arch\r | |
221 | RecordList = self._RawData[MODEL_EFI_PPI, self._Arch]\r | |
222 | for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:\r | |
223 | if PrivateFlag == 'PRIVATE':\r | |
224 | if Name not in PrivateNameList:\r | |
225 | PrivateNameList.append(Name)\r | |
226 | PrivatePpiDict[Arch, Name] = Guid\r | |
227 | if Name in PublicNameList:\r | |
228 | EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)\r | |
229 | else:\r | |
230 | if Name not in PublicNameList:\r | |
231 | PublicNameList.append(Name)\r | |
232 | if Name in PrivateNameList:\r | |
233 | EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)\r | |
234 | if Name not in NameList:\r | |
235 | NameList.append(Name)\r | |
236 | PpiDict[Arch, Name] = Guid\r | |
6e6d767e CJ |
237 | # use OrderedDict to keep the order\r |
238 | self._Ppis = OrderedDict()\r | |
239 | self._PrivatePpis = OrderedDict()\r | |
ae7b6df8 LG |
240 | for Name in NameList:\r |
241 | #\r | |
242 | # limit the ARCH to self._Arch, if no self._Arch found, tdict\r | |
243 | # will automatically turn to 'common' ARCH for trying\r | |
244 | #\r | |
245 | self._Ppis[Name] = PpiDict[self._Arch, Name]\r | |
246 | for Name in PrivateNameList:\r | |
247 | self._PrivatePpis[Name] = PrivatePpiDict[self._Arch, Name]\r | |
248 | return self._Ppis\r | |
249 | \r | |
250 | ## Retrieve GUID definitions (name/value pairs)\r | |
71cac3f7 CJ |
251 | @property\r |
252 | def Guids(self):\r | |
4231a819 | 253 | if self._Guids is None:\r |
ae7b6df8 LG |
254 | #\r |
255 | # tdict is a special kind of dict, used for selecting correct\r | |
256 | # GUID defition for given ARCH\r | |
257 | #\r | |
258 | GuidDict = tdict(True)\r | |
259 | PrivateGuidDict = tdict(True)\r | |
260 | NameList = []\r | |
261 | PrivateNameList = []\r | |
262 | PublicNameList = []\r | |
263 | # find out all protocol definitions for specific and 'common' arch\r | |
264 | RecordList = self._RawData[MODEL_EFI_GUID, self._Arch]\r | |
265 | for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:\r | |
266 | if PrivateFlag == 'PRIVATE':\r | |
267 | if Name not in PrivateNameList:\r | |
268 | PrivateNameList.append(Name)\r | |
269 | PrivateGuidDict[Arch, Name] = Guid\r | |
270 | if Name in PublicNameList:\r | |
271 | EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)\r | |
272 | else:\r | |
273 | if Name not in PublicNameList:\r | |
274 | PublicNameList.append(Name)\r | |
275 | if Name in PrivateNameList:\r | |
276 | EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)\r | |
277 | if Name not in NameList:\r | |
278 | NameList.append(Name)\r | |
279 | GuidDict[Arch, Name] = Guid\r | |
6e6d767e CJ |
280 | # use OrderedDict to keep the order\r |
281 | self._Guids = OrderedDict()\r | |
282 | self._PrivateGuids = OrderedDict()\r | |
ae7b6df8 LG |
283 | for Name in NameList:\r |
284 | #\r | |
285 | # limit the ARCH to self._Arch, if no self._Arch found, tdict\r | |
286 | # will automatically turn to 'common' ARCH for trying\r | |
287 | #\r | |
288 | self._Guids[Name] = GuidDict[self._Arch, Name]\r | |
289 | for Name in PrivateNameList:\r | |
290 | self._PrivateGuids[Name] = PrivateGuidDict[self._Arch, Name]\r | |
291 | return self._Guids\r | |
292 | \r | |
293 | ## Retrieve public include paths declared in this package\r | |
71cac3f7 CJ |
294 | @property\r |
295 | def Includes(self):\r | |
4231a819 | 296 | if self._Includes is None or self._CommonIncludes is None:\r |
0a57a978 | 297 | self._CommonIncludes = []\r |
ae7b6df8 LG |
298 | self._Includes = []\r |
299 | self._PrivateIncludes = []\r | |
300 | PublicInclues = []\r | |
301 | RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch]\r | |
302 | Macros = self._Macros\r | |
938cf4c3 | 303 | Macros["EDK_SOURCE"] = gEcpSource\r |
ae7b6df8 LG |
304 | for Record in RecordList:\r |
305 | File = PathClass(NormPath(Record[0], Macros), self._PackageDir, Arch=self._Arch)\r | |
306 | LineNo = Record[-1]\r | |
307 | # validate the path\r | |
308 | ErrorCode, ErrorInfo = File.Validate()\r | |
309 | if ErrorCode != 0:\r | |
310 | EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r | |
311 | \r | |
312 | # avoid duplicate include path\r | |
313 | if File not in self._Includes:\r | |
314 | self._Includes.append(File)\r | |
315 | if Record[4] == 'PRIVATE':\r | |
316 | if File not in self._PrivateIncludes:\r | |
317 | self._PrivateIncludes.append(File)\r | |
318 | if File in PublicInclues:\r | |
319 | EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % File, File=self.MetaFile, Line=LineNo)\r | |
320 | else:\r | |
321 | if File not in PublicInclues:\r | |
322 | PublicInclues.append(File)\r | |
323 | if File in self._PrivateIncludes:\r | |
324 | EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % File, File=self.MetaFile, Line=LineNo)\r | |
55c84777 | 325 | if Record[3] == TAB_COMMON:\r |
0a57a978 | 326 | self._CommonIncludes.append(File)\r |
ae7b6df8 LG |
327 | return self._Includes\r |
328 | \r | |
329 | ## Retrieve library class declarations (not used in build at present)\r | |
71cac3f7 CJ |
330 | @property\r |
331 | def LibraryClasses(self):\r | |
4231a819 | 332 | if self._LibraryClasses is None:\r |
ae7b6df8 LG |
333 | #\r |
334 | # tdict is a special kind of dict, used for selecting correct\r | |
335 | # library class declaration for given ARCH\r | |
336 | #\r | |
337 | LibraryClassDict = tdict(True)\r | |
338 | LibraryClassSet = set()\r | |
339 | RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]\r | |
340 | Macros = self._Macros\r | |
341 | for LibraryClass, File, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:\r | |
342 | File = PathClass(NormPath(File, Macros), self._PackageDir, Arch=self._Arch)\r | |
343 | # check the file validation\r | |
344 | ErrorCode, ErrorInfo = File.Validate()\r | |
345 | if ErrorCode != 0:\r | |
346 | EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r | |
347 | LibraryClassSet.add(LibraryClass)\r | |
348 | LibraryClassDict[Arch, LibraryClass] = File\r | |
6e6d767e | 349 | self._LibraryClasses = OrderedDict()\r |
ae7b6df8 LG |
350 | for LibraryClass in LibraryClassSet:\r |
351 | self._LibraryClasses[LibraryClass] = LibraryClassDict[self._Arch, LibraryClass]\r | |
352 | return self._LibraryClasses\r | |
353 | \r | |
354 | ## Retrieve PCD declarations\r | |
71cac3f7 CJ |
355 | @property\r |
356 | def Pcds(self):\r | |
4231a819 | 357 | if self._Pcds is None:\r |
6e6d767e | 358 | self._Pcds = OrderedDict()\r |
ae7b6df8 LG |
359 | self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r |
360 | self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r | |
361 | self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r | |
362 | self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC))\r | |
363 | self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))\r | |
364 | return self._Pcds\r | |
365 | \r | |
72a1d776 | 366 | def ParsePcdName(self,TokenCName):\r |
367 | TokenCName = TokenCName.strip()\r | |
368 | if TokenCName.startswith("["):\r | |
369 | if "." in TokenCName:\r | |
370 | Demesionattr = TokenCName[:TokenCName.index(".")]\r | |
371 | Fields = TokenCName[TokenCName.index(".")+1:]\r | |
372 | else:\r | |
373 | Demesionattr = TokenCName\r | |
374 | Fields = ""\r | |
375 | else:\r | |
376 | Demesionattr = ""\r | |
377 | Fields = TokenCName\r | |
378 | \r | |
379 | return Demesionattr,Fields\r | |
380 | \r | |
ae7b6df8 | 381 | def ProcessStructurePcd(self, StructurePcdRawDataSet):\r |
79820e32 | 382 | s_pcd_set = OrderedDict()\r |
ccaa7754 | 383 | for s_pcd, LineNo in StructurePcdRawDataSet:\r |
ae7b6df8 LG |
384 | if s_pcd.TokenSpaceGuidCName not in s_pcd_set:\r |
385 | s_pcd_set[s_pcd.TokenSpaceGuidCName] = []\r | |
ccaa7754 | 386 | s_pcd_set[s_pcd.TokenSpaceGuidCName].append((s_pcd, LineNo))\r |
ae7b6df8 LG |
387 | \r |
388 | str_pcd_set = []\r | |
389 | for pcdname in s_pcd_set:\r | |
390 | dep_pkgs = []\r | |
391 | struct_pcd = StructurePcd()\r | |
ccaa7754 | 392 | for item, LineNo in s_pcd_set[pcdname]:\r |
72a1d776 | 393 | if not item.TokenCName:\r |
394 | continue\r | |
ae7b6df8 | 395 | if "<HeaderFiles>" in item.TokenCName:\r |
81add864 | 396 | struct_pcd.StructuredPcdIncludeFile.append(item.DefaultValue)\r |
ae7b6df8 LG |
397 | elif "<Packages>" in item.TokenCName:\r |
398 | dep_pkgs.append(item.DefaultValue)\r | |
399 | elif item.DatumType == item.TokenCName:\r | |
400 | struct_pcd.copy(item)\r | |
401 | struct_pcd.TokenValue = struct_pcd.TokenValue.strip("{").strip()\r | |
402 | struct_pcd.TokenSpaceGuidCName, struct_pcd.TokenCName = pcdname.split(".")\r | |
6a103440 FB |
403 | struct_pcd.PcdDefineLineNo = LineNo\r |
404 | struct_pcd.PkgPath = self.MetaFile.File\r | |
06140766 | 405 | struct_pcd.SetDecDefaultValue(item.DefaultValue)\r |
ae7b6df8 | 406 | else:\r |
72a1d776 | 407 | DemesionAttr, Fields = self.ParsePcdName(item.TokenCName)\r |
408 | struct_pcd.AddDefaultValue(Fields, item.DefaultValue, self.MetaFile.File, LineNo,DemesionAttr)\r | |
ae7b6df8 LG |
409 | \r |
410 | struct_pcd.PackageDecs = dep_pkgs\r | |
ae7b6df8 | 411 | str_pcd_set.append(struct_pcd)\r |
ae7b6df8 LG |
412 | return str_pcd_set\r |
413 | \r | |
414 | ## Retrieve PCD declarations for given type\r | |
415 | def _GetPcd(self, Type):\r | |
6e6d767e | 416 | Pcds = OrderedDict()\r |
ae7b6df8 LG |
417 | #\r |
418 | # tdict is a special kind of dict, used for selecting correct\r | |
419 | # PCD declaration for given ARCH\r | |
420 | #\r | |
421 | PcdDict = tdict(True, 3)\r | |
422 | # for summarizing PCD\r | |
e651d06c | 423 | PcdSet = []\r |
ae7b6df8 LG |
424 | # find out all PCDs of the 'type'\r |
425 | \r | |
426 | StrPcdSet = []\r | |
427 | RecordList = self._RawData[Type, self._Arch]\r | |
428 | for TokenSpaceGuid, PcdCName, Setting, Arch, PrivateFlag, Dummy1, Dummy2 in RecordList:\r | |
ccaa7754 | 429 | PcdDict[Arch, PcdCName, TokenSpaceGuid] = (Setting, Dummy2)\r |
e651d06c LG |
430 | if not (PcdCName, TokenSpaceGuid) in PcdSet:\r |
431 | PcdSet.append((PcdCName, TokenSpaceGuid))\r | |
ae7b6df8 | 432 | \r |
6f73a036 | 433 | DefinitionPosition = {}\r |
ae7b6df8 LG |
434 | for PcdCName, TokenSpaceGuid in PcdSet:\r |
435 | #\r | |
436 | # limit the ARCH to self._Arch, if no self._Arch found, tdict\r | |
437 | # will automatically turn to 'common' ARCH and try again\r | |
438 | #\r | |
ccaa7754 | 439 | Setting, LineNo = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]\r |
4231a819 | 440 | if Setting is None:\r |
ae7b6df8 LG |
441 | continue\r |
442 | \r | |
443 | DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting)\r | |
444 | validateranges, validlists, expressions = self._RawData.GetValidExpression(TokenSpaceGuid, PcdCName)\r | |
445 | PcdObj = PcdClassObject(\r | |
446 | PcdCName,\r | |
447 | TokenSpaceGuid,\r | |
448 | self._PCD_TYPE_STRING_[Type],\r | |
449 | DatumType,\r | |
450 | DefaultValue,\r | |
451 | TokenNumber,\r | |
452 | '',\r | |
453 | {},\r | |
454 | False,\r | |
455 | None,\r | |
456 | list(validateranges),\r | |
457 | list(validlists),\r | |
458 | list(expressions)\r | |
459 | )\r | |
6f73a036 | 460 | DefinitionPosition[PcdObj] = (self.MetaFile.File, LineNo)\r |
ae7b6df8 | 461 | if "." in TokenSpaceGuid:\r |
ccaa7754 | 462 | StrPcdSet.append((PcdObj, LineNo))\r |
ae7b6df8 LG |
463 | else:\r |
464 | Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdObj\r | |
465 | \r | |
466 | StructurePcds = self.ProcessStructurePcd(StrPcdSet)\r | |
467 | for pcd in StructurePcds:\r | |
468 | Pcds[pcd.TokenCName, pcd.TokenSpaceGuidCName, self._PCD_TYPE_STRING_[Type]] = pcd\r | |
938cf4c3 | 469 | StructPattern = compile(r'[_a-zA-Z][0-9A-Za-z_]*$')\r |
065a7d40 FB |
470 | for pcd in Pcds.values():\r |
471 | if pcd.DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]:\r | |
72a1d776 | 472 | if not pcd.IsAggregateDatumType():\r |
6f73a036 | 473 | EdkLogger.error('build', FORMAT_INVALID, "DatumType only support BOOLEAN, UINT8, UINT16, UINT32, UINT64, VOID* or a valid struct name.", DefinitionPosition[pcd][0], DefinitionPosition[pcd][1])\r |
72a1d776 | 474 | elif not pcd.IsArray() and not pcd.StructuredPcdIncludeFile:\r |
475 | EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "The structure Pcd %s.%s header file is not found in %s line %s \n" % (pcd.TokenSpaceGuidCName, pcd.TokenCName, pcd.DefinitionPosition[0], pcd.DefinitionPosition[1] ))\r | |
ae7b6df8 | 476 | return Pcds\r |
71cac3f7 | 477 | \r |
0a57a978 FB |
478 | @property\r |
479 | def CommonIncludes(self):\r | |
480 | if self._CommonIncludes is None:\r | |
481 | self.Includes\r | |
482 | return self._CommonIncludes\r |