]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/baseobject.py
BaseTools: Remove the deprecated hash_key()
[mirror_edk2.git] / BaseTools / Scripts / PackageDocumentTools / plugins / EdkPlugins / edk2 / model / baseobject.py
1 ## @file
2 #
3 # Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
4 #
5 # This program and the accompanying materials are licensed and made available
6 # under the terms and conditions of the BSD License which accompanies this
7 # 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 import plugins.EdkPlugins.basemodel.ini as ini
14 import plugins.EdkPlugins.edk2.model.dsc as dsc
15 import plugins.EdkPlugins.edk2.model.inf as inf
16 import plugins.EdkPlugins.edk2.model.dec as dec
17 import os
18 from plugins.EdkPlugins.basemodel.message import *
19
20 class SurfaceObject(object):
21 _objs = {}
22
23 def __new__(cls, *args, **kwargs):
24 """Maintain only a single instance of this object
25 @return: instance of this class
26
27 """
28 obj = object.__new__(cls, *args, **kwargs)
29 if "None" not in cls._objs:
30 cls._objs["None"] = []
31 cls._objs["None"].append(obj)
32
33 return obj
34
35 def __init__(self, parent, workspace):
36 self._parent = parent
37 self._fileObj = None
38 self._workspace = workspace
39 self._isModify = False
40 self._modifiedObjs = []
41
42 def __del__(self):
43 pass
44
45 def Destroy(self):
46 key = self.GetRelativeFilename()
47 self.GetFileObj().Destroy(self)
48 del self._fileObj
49 # dereference self from _objs arrary
50 assert key in self._objs, "when destory, object is not in obj list"
51 assert self in self._objs[key], "when destory, object is not in obj list"
52 self._objs[key].remove(self)
53 if len(self._objs[key]) == 0:
54 del self._objs[key]
55
56 def GetParent(self):
57 return self._parent
58
59 def GetWorkspace(self):
60 return self._workspace
61
62 def GetFileObjectClass(self):
63 return ini.BaseINIFile
64
65 def GetFilename(self):
66 return self.GetFileObj().GetFilename()
67
68 def GetFileObj(self):
69 return self._fileObj
70
71 def GetRelativeFilename(self):
72 fullPath = self.GetFilename()
73 return fullPath[len(self._workspace) + 1:]
74
75 def Load(self, relativePath):
76 # if has been loaded, directly return
77 if self._fileObj is not None: return True
78
79 relativePath = os.path.normpath(relativePath)
80 fullPath = os.path.join(self._workspace, relativePath)
81 fullPath = os.path.normpath(fullPath)
82
83 if not os.path.exists(fullPath):
84 ErrorMsg("file does not exist!", fullPath)
85 return False
86
87 self._fileObj = self.GetFileObjectClass()(fullPath, self)
88
89 if not self._fileObj.Parse():
90 ErrorMsg("Fail to parse file!", fullPath)
91 return False
92
93 # remove self from None list to list with filename as key
94 cls = self.__class__
95 if self not in cls._objs["None"]:
96 ErrorMsg("Sufrace object does not be create into None list")
97 cls._objs["None"].remove(self)
98 if relativePath not in cls._objs:
99 cls._objs[relativePath] = []
100 cls._objs[relativePath].append(self)
101
102 return True
103
104 def Reload(self, force=False):
105 ret = True
106 # whether require must be update
107 if force:
108 ret = self.GetFileObj().Reload(True)
109 else:
110 if self.IsModified():
111 if self.GetFileObj().IsModified():
112 ret = self.GetFileObj().Reload()
113 return ret
114
115 def Modify(self, modify=True, modifiedObj=None):
116 if modify:
117 #LogMsg("%s is modified, modified object is %s" % (self.GetFilename(), modifiedObj))
118 if issubclass(modifiedObj.__class__, ini.BaseINIFile) and self._isModify:
119 return
120 self._isModify = modify
121 self.GetParent().Modify(modify, self)
122 else:
123 self._isModify = modify
124
125 def IsModified(self):
126 return self._isModify
127
128 def GetModifiedObjs(self):
129 return self._modifiedObjs
130
131 def FilterObjsByArch(self, objs, arch):
132 arr = []
133 for obj in objs:
134 if obj.GetArch().lower() == 'common':
135 arr.append(obj)
136 continue
137 if obj.GetArch().lower() == arch.lower():
138 arr.append(obj)
139 continue
140 return arr
141
142 class Platform(SurfaceObject):
143 def __init__(self, parent, workspace):
144 SurfaceObject.__init__(self, parent, workspace)
145 self._modules = []
146 self._packages = []
147
148 def Destroy(self):
149 for module in self._modules:
150 module.Destroy()
151 del self._modules[:]
152
153 del self._packages[:]
154 SurfaceObject.Destroy(self)
155
156 def GetName(self):
157 return self.GetFileObj().GetDefine("PLATFORM_NAME")
158
159 def GetFileObjectClass(self):
160 return dsc.DSCFile
161
162 def GetModuleCount(self):
163 if self.GetFileObj() is None:
164 ErrorMsg("Fail to get module count because DSC file has not been load!")
165
166 return len(self.GetFileObj().GetComponents())
167
168 def GetSupportArchs(self):
169 return self.GetFileObj().GetDefine("SUPPORTED_ARCHITECTURES").strip().split('#')[0].split('|')
170
171 def LoadModules(self, precallback=None, postcallback=None):
172 for obj in self.GetFileObj().GetComponents():
173 mFilename = obj.GetFilename()
174 if precallback is not None:
175 precallback(self, mFilename)
176 arch = obj.GetArch()
177 if arch.lower() == 'common':
178 archarr = self.GetSupportArchs()
179 else:
180 archarr = [arch]
181 for arch in archarr:
182 module = Module(self, self.GetWorkspace())
183 if module.Load(mFilename, arch, obj.GetOveridePcds(), obj.GetOverideLibs()):
184 self._modules.append(module)
185 if postcallback is not None:
186 postcallback(self, module)
187 else:
188 del module
189 ErrorMsg("Fail to load module %s" % mFilename)
190
191 def GetModules(self):
192 return self._modules
193
194 def GetLibraryPath(self, classname, arch, type):
195 objs = self.GetFileObj().GetSectionObjectsByName("libraryclasses")
196
197 for obj in objs:
198 if classname.lower() != obj.GetClass().lower():
199 continue
200 if obj.GetArch().lower() != 'common' and \
201 obj.GetArch().lower() != arch.lower():
202 continue
203
204 if obj.GetModuleType().lower() != 'common' and \
205 obj.GetModuleType().lower() != type.lower():
206 continue
207
208 return obj.GetInstance()
209
210 ErrorMsg("Fail to get library class %s [%s][%s] from platform %s" % (classname, arch, type, self.GetFilename()))
211 return None
212
213 def GetPackage(self, path):
214 package = self.GetParent().GetPackage(path)
215 if package not in self._packages:
216 self._packages.append(package)
217 return package
218
219 def GetPcdBuildObjs(self, name, arch=None):
220 arr = []
221 objs = self.GetFileObj().GetSectionObjectsByName('pcds')
222 for obj in objs:
223 if obj.GetPcdName().lower() == name.lower():
224 arr.append(obj)
225 if arch is not None:
226 arr = self.FilterObjsByArch(arr, arch)
227 return arr
228
229 def Reload(self, callback=None):
230 # do not care force paramter for platform object
231 isFileChanged = self.GetFileObj().IsModified()
232 ret = SurfaceObject.Reload(self, False)
233 if not ret: return False
234 if isFileChanged:
235 # destroy all modules and reload them again
236 for obj in self._modules:
237 obj.Destroy()
238 del self._modules[:]
239 del self._packages[:]
240 self.LoadModules(callback)
241 else:
242 for obj in self._modules:
243 callback(self, obj.GetFilename())
244 obj.Reload()
245
246 self.Modify(False)
247 return True
248
249 def Modify(self, modify=True, modifiedObj=None):
250 if modify:
251 #LogMsg("%s is modified, modified object is %s" % (self.GetFilename(), modifiedObj))
252 if issubclass(modifiedObj.__class__, ini.BaseINIFile) and self._isModify:
253 return
254 self._isModify = modify
255 self.GetParent().Modify(modify, self)
256 else:
257 if self.GetFileObj().IsModified():
258 return
259 for obj in self._modules:
260 if obj.IsModified():
261 return
262
263 self._isModify = modify
264 self.GetParent().Modify(modify, self)
265
266 def GetModuleObject(self, relativePath, arch):
267 path = os.path.normpath(relativePath)
268 for obj in self._modules:
269 if obj.GetRelativeFilename() == path:
270 if arch.lower() == 'common':
271 return obj
272 if obj.GetArch() == arch:
273 return obj
274 return None
275
276 def GenerateFullReferenceDsc(self):
277 oldDsc = self.GetFileObj()
278 newDsc = dsc.DSCFile()
279 newDsc.CopySectionsByName(oldDsc, 'defines')
280 newDsc.CopySectionsByName(oldDsc, 'SkuIds')
281
282 #
283 # Dynamic common section should also be copied
284 #
285 newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicDefault')
286 newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicHii')
287 newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicVpd')
288 newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicEx')
289
290 sects = oldDsc.GetSectionByName('Components')
291 for oldSect in sects:
292 newSect = newDsc.AddNewSection(oldSect.GetName())
293 for oldComObj in oldSect.GetObjects():
294 module = self.GetModuleObject(oldComObj.GetFilename(), oldSect.GetArch())
295 if module is None: continue
296
297 newComObj = dsc.DSCComponentObject(newSect)
298 newComObj.SetFilename(oldComObj.GetFilename())
299
300 # add all library instance for override section
301 libdict = module.GetLibraries()
302 for libclass in libdict.keys():
303 if libdict[libclass] is not None:
304 newComObj.AddOverideLib(libclass, libdict[libclass].GetRelativeFilename().replace('\\', '/'))
305
306 # add all pcds for override section
307 pcddict = module.GetPcds()
308 for pcd in pcddict.values():
309 buildPcd = pcd.GetBuildObj()
310 buildType = buildPcd.GetPcdType()
311 buildValue = None
312 if buildType.lower() == 'pcdsdynamichii' or \
313 buildType.lower() == 'pcdsdynamicvpd' or \
314 buildType.lower() == 'pcdsdynamicdefault':
315 buildType = 'PcdsDynamic'
316 if buildType != 'PcdsDynamic':
317 buildValue = buildPcd.GetPcdValue()
318 newComObj.AddOveridePcd(buildPcd.GetPcdName(),
319 buildType,
320 buildValue)
321 newSect.AddObject(newComObj)
322 return newDsc
323
324 class Module(SurfaceObject):
325 def __init__(self, parent, workspace):
326 SurfaceObject.__init__(self, parent, workspace)
327 self._arch = 'common'
328 self._parent = parent
329 self._overidePcds = {}
330 self._overideLibs = {}
331 self._libs = {}
332 self._pcds = {}
333 self._ppis = []
334 self._protocols = []
335 self._depexs = []
336 self._guids = []
337 self._packages = []
338
339 def Destroy(self):
340 for lib in self._libs.values():
341 if lib is not None:
342 lib.Destroy()
343 self._libs.clear()
344
345 for pcd in self._pcds.values():
346 pcd.Destroy()
347 self._pcds.clear()
348
349 for ppi in self._ppis:
350 ppi.DeRef(self)
351 del self._ppis[:]
352
353 for protocol in self._protocols:
354 if protocol is not None:
355 protocol.DeRef(self)
356 del self._protocols[:]
357
358 for guid in self._guids:
359 if guid is not None:
360 guid.DeRef(self)
361 del self._guids[:]
362
363 del self._packages[:]
364 del self._depexs[:]
365 SurfaceObject.Destroy(self)
366
367 def GetFileObjectClass(self):
368 return inf.INFFile
369
370 def GetLibraries(self):
371 return self._libs
372
373 def Load(self, filename, arch='common', overidePcds=None, overideLibs=None):
374 if not SurfaceObject.Load(self, filename):
375 return False
376
377 self._arch = arch
378 if overidePcds is not None:
379 self._overideLibs = overideLibs
380 if overideLibs is not None:
381 self._overidePcds = overidePcds
382
383 self._SearchLibraries()
384 self._SearchPackage()
385 self._SearchSurfaceItems()
386 return True
387
388 def GetArch(self):
389 return self._arch
390
391 def GetModuleName(self):
392 return self.GetFileObj().GetDefine("BASE_NAME")
393
394 def GetModuleType(self):
395 return self.GetFileObj().GetDefine("MODULE_TYPE")
396
397 def GetPlatform(self):
398 return self.GetParent()
399
400 def GetModuleObj(self):
401 return self
402
403 def GetPcds(self):
404 pcds = self._pcds.copy()
405 for lib in self._libs.values():
406 if lib is None: continue
407 for name in lib._pcds.keys():
408 pcds[name] = lib._pcds[name]
409 return pcds
410
411 def GetPpis(self):
412 ppis = []
413 ppis += self._ppis
414 for lib in self._libs.values():
415 if lib is None: continue
416 ppis += lib._ppis
417 return ppis
418
419 def GetProtocols(self):
420 pros = []
421 pros = self._protocols
422 for lib in self._libs.values():
423 if lib is None: continue
424 pros += lib._protocols
425 return pros
426
427 def GetGuids(self):
428 guids = []
429 guids += self._guids
430 for lib in self._libs.values():
431 if lib is None: continue
432 guids += lib._guids
433 return guids
434
435 def GetDepexs(self):
436 deps = []
437 deps += self._depexs
438 for lib in self._libs.values():
439 if lib is None: continue
440 deps += lib._depexs
441 return deps
442
443 def IsLibrary(self):
444 return self.GetFileObj().GetDefine("LIBRARY_CLASS") is not None
445
446 def GetLibraryInstance(self, classname, arch, type):
447 if classname not in self._libs.keys():
448 # find in overide lib firstly
449 if classname in self._overideLibs.keys():
450 self._libs[classname] = Library(self, self.GetWorkspace())
451 self._libs[classname].Load(self._overideLibs[classname])
452 return self._libs[classname]
453
454 parent = self.GetParent()
455 if issubclass(parent.__class__, Platform):
456 path = parent.GetLibraryPath(classname, arch, type)
457 if path is None:
458 ErrorMsg('Fail to get library instance for %s' % classname, self.GetFilename())
459 return None
460 self._libs[classname] = Library(self, self.GetWorkspace())
461 if not self._libs[classname].Load(path, self.GetArch()):
462 self._libs[classname] = None
463 else:
464 self._libs[classname] = parent.GetLibraryInstance(classname, arch, type)
465 return self._libs[classname]
466
467 def GetSourceObjs(self):
468 return self.GetFileObj().GetSectionObjectsByName('source')
469
470 def _SearchLibraries(self):
471 objs = self.GetFileObj().GetSectionObjectsByName('libraryclasses')
472 arch = self.GetArch()
473 type = self.GetModuleType()
474 for obj in objs:
475 if obj.GetArch().lower() != 'common' and \
476 obj.GetArch().lower() not in self.GetPlatform().GetSupportArchs():
477 continue
478 classname = obj.GetClass()
479 instance = self.GetLibraryInstance(classname, arch, type)
480 if not self.IsLibrary() and instance is not None:
481 instance._isInherit = False
482
483 if classname not in self._libs.keys():
484 self._libs[classname] = instance
485
486 def _SearchSurfaceItems(self):
487 # get surface item from self's inf
488 pcds = []
489 ppis = []
490 pros = []
491 deps = []
492 guids = []
493 if self.GetFileObj() is not None:
494 pcds = self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('pcd'),
495 self.GetArch())
496 for pcd in pcds:
497 if pcd.GetPcdName() not in self._pcds.keys():
498 pcdItem = PcdItem(pcd.GetPcdName(), self, pcd)
499 self._pcds[pcd.GetPcdName()] = ModulePcd(self,
500 pcd.GetPcdName(),
501 pcd,
502 pcdItem)
503
504 ppis += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('ppis'),
505 self.GetArch())
506
507 for ppi in ppis:
508 item = PpiItem(ppi.GetName(), self, ppi)
509 if item not in self._ppis:
510 self._ppis.append(item)
511
512 pros += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('protocols'),
513 self.GetArch())
514
515 for pro in pros:
516 item = ProtocolItem(pro.GetName(), self, pro)
517 if item not in self._protocols:
518 self._protocols.append(item)
519
520 deps += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('depex'),
521 self.GetArch())
522 for dep in deps:
523 item = DepexItem(self, dep)
524 self._depexs.append(item)
525
526 guids += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('guids'),
527 self.GetArch())
528 for guid in guids:
529 item = GuidItem(guid.GetName(), self, guid)
530 if item not in self._guids:
531 self._guids.append(item)
532
533 def _SearchPackage(self):
534 objs = self.GetFileObj().GetSectionObjectsByName('packages')
535 for obj in objs:
536 package = self.GetPlatform().GetPackage(obj.GetPath())
537 if package is not None:
538 self._packages.append(package)
539
540 def GetPackages(self):
541 return self._packages
542
543 def GetPcdObjects(self):
544 if self.GetFileObj() is None:
545 return []
546
547 return self.GetFileObj().GetSectionObjectsByName('pcd')
548
549 def GetLibraryClassHeaderFilePath(self):
550 lcname = self.GetFileObj().GetProduceLibraryClass()
551 if lcname is None: return None
552
553 pkgs = self.GetPackages()
554 for package in pkgs:
555 path = package.GetLibraryClassHeaderPathByName(lcname)
556 if path is not None:
557 return os.path.realpath(os.path.join(package.GetFileObj().GetPackageRootPath(), path))
558 return None
559
560 def Reload(self, force=False, callback=None):
561 if callback is not None:
562 callback(self, "Starting reload...")
563
564 ret = SurfaceObject.Reload(self, force)
565 if not ret: return False
566
567 if not force and not self.IsModified():
568 return True
569
570 for lib in self._libs.values():
571 if lib is not None:
572 lib.Destroy()
573 self._libs.clear()
574
575 for pcd in self._pcds.values():
576 pcd.Destroy()
577 self._pcds.clear()
578
579 for ppi in self._ppis:
580 ppi.DeRef(self)
581 del self._ppis[:]
582
583 for protocol in self._protocols:
584 protocol.DeRef(self)
585 del self._protocols[:]
586
587 for guid in self._guids:
588 guid.DeRef(self)
589 del self._guids[:]
590
591 del self._packages[:]
592 del self._depexs[:]
593
594 if callback is not None:
595 callback(self, "Searching libraries...")
596 self._SearchLibraries()
597 if callback is not None:
598 callback(self, "Searching packages...")
599 self._SearchPackage()
600 if callback is not None:
601 callback(self, "Searching surface items...")
602 self._SearchSurfaceItems()
603
604 self.Modify(False)
605 return True
606
607 def Modify(self, modify=True, modifiedObj=None):
608 if modify:
609 #LogMsg("%s is modified, modified object is %s" % (self.GetFilename(), modifiedObj))
610 if issubclass(modifiedObj.__class__, ini.BaseINIFile) and self._isModify:
611 return
612 self._isModify = modify
613 self.GetParent().Modify(modify, self)
614 else:
615 if self.GetFileObj().IsModified():
616 return
617
618 self._isModify = modify
619 self.GetParent().Modify(modify, self)
620
621 class Library(Module):
622 def __init__(self, parent, workspace):
623 Module.__init__(self, parent, workspace)
624 self._isInherit = True
625
626 def IsInherit(self):
627 return self._isInherit
628
629 def GetModuleType(self):
630 return self.GetParent().GetModuleType()
631
632 def GetPlatform(self):
633 return self.GetParent().GetParent()
634
635 def GetModuleObj(self):
636 return self.GetParent()
637
638 def GetArch(self):
639 return self.GetParent().GetArch()
640
641 def Destroy(self):
642 self._libs.clear()
643 self._pcds.clear()
644 SurfaceObject.Destroy(self)
645
646 class Package(SurfaceObject):
647 def __init__(self, parent, workspace):
648 SurfaceObject.__init__(self, parent, workspace)
649 self._pcds = {}
650 self._guids = {}
651 self._protocols = {}
652 self._ppis = {}
653
654 def GetPcds(self):
655 return self._pcds
656
657 def GetPpis(self):
658 return self._ppis.values()
659
660 def GetProtocols(self):
661 return self._protocols.values()
662
663 def GetGuids(self):
664 return self._guids.values()
665
666 def Destroy(self):
667 for pcd in self._pcds.values():
668 if pcd is not None:
669 pcd.Destroy()
670 for guid in self._guids.values():
671 if guid is not None:
672 guid.Destroy()
673 for protocol in self._protocols.values():
674 if protocol is not None:
675 protocol.Destroy()
676 for ppi in self._ppis.values():
677 if ppi is not None:
678 ppi.Destroy()
679 self._pcds.clear()
680 self._guids.clear()
681 self._protocols.clear()
682 self._ppis.clear()
683 self._pcds.clear()
684 SurfaceObject.Destroy(self)
685
686 def Load(self, relativePath):
687 ret = SurfaceObject.Load(self, relativePath)
688 if not ret: return False
689 pcds = self.GetFileObj().GetSectionObjectsByName('pcds')
690 for pcd in pcds:
691 if pcd.GetPcdName() in self._pcds.keys():
692 if self._pcds[pcd.GetPcdName()] is not None:
693 self._pcds[pcd.GetPcdName()].AddDecObj(pcd)
694 else:
695 self._pcds[pcd.GetPcdName()] = PcdItem(pcd.GetPcdName(), self, pcd)
696
697 guids = self.GetFileObj().GetSectionObjectsByName('guids')
698 for guid in guids:
699 if guid.GetName() not in self._guids.keys():
700 self._guids[guid.GetName()] = GuidItem(guid.GetName(), self, guid)
701 else:
702 WarnMsg("Duplicate definition for %s" % guid.GetName())
703
704 ppis = self.GetFileObj().GetSectionObjectsByName('ppis')
705 for ppi in ppis:
706 if ppi.GetName() not in self._ppis.keys():
707 self._ppis[ppi.GetName()] = PpiItem(ppi.GetName(), self, ppi)
708 else:
709 WarnMsg("Duplicate definition for %s" % ppi.GetName())
710
711 protocols = self.GetFileObj().GetSectionObjectsByName('protocols')
712 for protocol in protocols:
713 if protocol.GetName() not in self._protocols.keys():
714 self._protocols[protocol.GetName()] = ProtocolItem(protocol.GetName(), self, protocol)
715 else:
716 WarnMsg("Duplicate definition for %s" % protocol.GetName())
717
718 return True
719
720 def GetFileObjectClass(self):
721 return dec.DECFile
722
723 def GetName(self):
724 return self.GetFileObj().GetDefine("PACKAGE_NAME")
725
726 def GetPcdDefineObjs(self, name=None):
727 arr = []
728 objs = self.GetFileObj().GetSectionObjectsByName('pcds')
729 if name is None: return objs
730
731 for obj in objs:
732 if obj.GetPcdName().lower() == name.lower():
733 arr.append(obj)
734 return arr
735
736 def GetLibraryClassObjs(self):
737 return self.GetFileObj().GetSectionObjectsByName('libraryclasses')
738
739 def Modify(self, modify=True, modifiedObj=None):
740 if modify:
741 self._isModify = modify
742 self.GetParent().Modify(modify, self)
743 else:
744 if self.GetFileObj().IsModified():
745 return
746
747 self._isModify = modify
748 self.GetParent().Modify(modify, self)
749
750 def GetLibraryClassHeaderPathByName(self, clsname):
751 objs = self.GetLibraryClassObjs()
752 for obj in objs:
753 if obj.GetClassName() == clsname:
754 return obj.GetHeaderFile()
755 return None
756
757 class DepexItem(object):
758 def __init__(self, parent, infObj):
759 self._parent = parent
760 self._infObj = infObj
761
762 def GetDepexString(self):
763 return str(self._infObj)
764
765 def GetInfObject(self):
766 return self._infObj
767
768 class ModulePcd(object):
769 _type_mapping = {'FeaturePcd': 'PcdsFeatureFlag',
770 'FixedPcd': 'PcdsFixedAtBuild',
771 'PatchPcd': 'PcdsPatchableInModule'}
772
773 def __init__(self, parent, name, infObj, pcdItem):
774 assert issubclass(parent.__class__, Module), "Module's PCD's parent must be module!"
775 assert pcdItem is not None, 'Pcd %s does not in some package!' % name
776
777 self._name = name
778 self._parent = parent
779 self._pcdItem = pcdItem
780 self._infObj = infObj
781
782 def GetName(self):
783 return self._name
784
785 def GetParent(self):
786 return self._name
787
788 def GetArch(self):
789 return self._parent.GetArch()
790
791 def Destroy(self):
792 self._pcdItem.DeRef(self._parent)
793 self._infObj = None
794
795 def GetBuildObj(self):
796 platformInfos = self._parent.GetPlatform().GetPcdBuildObjs(self._name, self.GetArch())
797 modulePcdType = self._infObj.GetPcdType()
798
799 # if platform do not gives pcd's value, get default value from package
800 if len(platformInfos) == 0:
801 if modulePcdType.lower() == 'pcd':
802 return self._pcdItem.GetDecObject()
803 else:
804 for obj in self._pcdItem.GetDecObjects():
805 if modulePcdType not in self._type_mapping.keys():
806 ErrorMsg("Invalid PCD type %s" % modulePcdType)
807 return None
808
809 if self._type_mapping[modulePcdType] == obj.GetPcdType():
810 return obj
811 ErrorMsg ('Module PCD type %s does not in valied range [%s] in package!' % \
812 (modulePcdType))
813 else:
814 if modulePcdType.lower() == 'pcd':
815 if len(platformInfos) > 1:
816 WarnMsg("Find more than one value for PCD %s in platform %s" % \
817 (self._name, self._parent.GetPlatform().GetFilename()))
818 return platformInfos[0]
819 else:
820 for obj in platformInfos:
821 if modulePcdType not in self._type_mapping.keys():
822 ErrorMsg("Invalid PCD type %s" % modulePcdType)
823 return None
824
825 if self._type_mapping[modulePcdType] == obj.GetPcdType():
826 return obj
827
828 ErrorMsg('Can not find value for pcd %s in pcd type %s' % \
829 (self._name, modulePcdType))
830 return None
831
832
833 class SurfaceItem(object):
834 _objs = {}
835
836 def __new__(cls, *args, **kwargs):
837 """Maintain only a single instance of this object
838 @return: instance of this class
839
840 """
841 name = args[0]
842 parent = args[1]
843 fileObj = args[2]
844 if issubclass(parent.__class__, Package):
845 if name in cls._objs.keys():
846 ErrorMsg("%s item is duplicated defined in packages: %s and %s" %
847 (name, parent.GetFilename(), cls._objs[name].GetParent().GetFilename()))
848 return None
849 obj = object.__new__(cls, *args, **kwargs)
850 cls._objs[name] = obj
851 return obj
852 elif issubclass(parent.__class__, Module):
853 if name not in cls._objs.keys():
854 ErrorMsg("%s item does not defined in any package! It is used by module %s" % \
855 (name, parent.GetFilename()))
856 return None
857 return cls._objs[name]
858
859 return None
860
861
862 def __init__(self, name, parent, fileObj):
863 if issubclass(parent.__class__, Package):
864 self._name = name
865 self._parent = parent
866 self._decObj = [fileObj]
867 self._refMods = {}
868 else:
869 self.RefModule(parent, fileObj)
870
871 @classmethod
872 def GetObjectDict(cls):
873 return cls._objs
874
875 def GetParent(self):
876 return self._parent
877
878 def GetReference(self):
879 return self._refMods
880
881 def RefModule(self, mObj, infObj):
882 if mObj in self._refMods.keys():
883 return
884 self._refMods[mObj] = infObj
885
886 def DeRef(self, mObj):
887 if mObj not in self._refMods.keys():
888 WarnMsg("%s is not referenced by module %s" % (self._name, mObj.GetFilename()))
889 return
890 del self._refMods[mObj]
891
892 def Destroy(self):
893 self._refMods.clear()
894 cls = self.__class__
895 del cls._objs[self._name]
896
897 def GetName(self):
898 return self._name
899
900 def GetDecObject(self):
901 return self._decObj[0]
902
903 def GetDecObjects(self):
904 return self._decObj
905
906 class PcdItem(SurfaceItem):
907 def AddDecObj(self, fileObj):
908 for decObj in self._decObj:
909 if decObj.GetFilename() != fileObj.GetFilename():
910 ErrorMsg("Pcd %s defined in more than one packages : %s and %s" % \
911 (self._name, decObj.GetFilename(), fileObj.GetFilename()))
912 return
913 if decObj.GetPcdType() == fileObj.GetPcdType() and \
914 decObj.GetArch().lower() == fileObj.GetArch():
915 ErrorMsg("Pcd %s is duplicated defined in pcd type %s in package %s" % \
916 (self._name, decObj.GetPcdType(), decObj.GetFilename()))
917 return
918 self._decObj.append(fileObj)
919
920 def GetValidPcdType(self):
921 types = []
922 for obj in self._decObj:
923 if obj.GetPcdType() not in types:
924 types += obj.GetPcdType()
925 return types
926
927 class GuidItem(SurfaceItem):
928 pass
929
930 class PpiItem(SurfaceItem):
931 pass
932
933 class ProtocolItem(SurfaceItem):
934 pass