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