• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1## @file DecPomAlignment.py
2# This file contained the adapter for convert INF parser object to POM Object
3#
4# Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
5#
6# This program and the accompanying materials are licensed and made available
7# under the terms and conditions of the BSD License which accompanies this
8# distribution. The full text of the license may be found at
9# http://opensource.org/licenses/bsd-license.php
10#
11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13#
14
15'''
16DecPomAlignment
17'''
18
19##
20# Import Modules
21#
22import os.path
23from os import sep
24import platform
25
26import re
27import Logger.Log as Logger
28from Logger import StringTable as ST
29from Logger.ToolError import UPT_MUL_DEC_ERROR
30from Logger.ToolError import FORMAT_INVALID
31
32from Library.Parsing import NormPath
33from Library.DataType import ARCH_LIST
34from Library.DataType import TAB_GUIDS
35from Library.DataType import TAB_PROTOCOLS
36from Library.DataType import TAB_PPIS
37from Library.DataType import TAB_DEC_DEFINES_PACKAGE_NAME
38from Library.DataType import TAB_DEC_DEFINES_PACKAGE_GUID
39from Library.DataType import TAB_DEC_DEFINES_PACKAGE_VERSION
40from Library.DataType import TAB_DEC_DEFINES_DEC_SPECIFICATION
41from Library.DataType import TAB_DEC_DEFINES_PKG_UNI_FILE
42from Library.DataType import TAB_ARCH_COMMON
43from Library.DataType import TAB_INCLUDES
44from Library.DataType import TAB_LIBRARY_CLASSES
45from Library.DataType import TAB_PCDS
46from Library.DataType import TAB_PCDS_FIXED_AT_BUILD_NULL
47from Library.DataType import TAB_PCDS_PATCHABLE_IN_MODULE_NULL
48from Library.DataType import TAB_PCDS_FEATURE_FLAG_NULL
49from Library.DataType import TAB_PCDS_DYNAMIC_EX_NULL
50from Library.DataType import TAB_PCDS_DYNAMIC_NULL
51from Library.DataType import TAB_PTR_TYPE_PCD
52from Library.DataType import ITEM_UNDEFINED
53from Library.DataType import TAB_DEC_BINARY_ABSTRACT
54from Library.DataType import TAB_DEC_BINARY_DESCRIPTION
55from Library.DataType import TAB_LANGUAGE_EN_US
56from Library.DataType import TAB_BINARY_HEADER_IDENTIFIER
57from Library.DataType import TAB_BINARY_HEADER_USERID
58from Library.DataType import TAB_LANGUAGE_EN_X
59from Library.DataType import TAB_LANGUAGE_EN
60from Library.DataType import TAB_STR_TOKENCNAME
61from Library.DataType import TAB_STR_TOKENPROMPT
62from Library.DataType import TAB_STR_TOKENHELP
63from Library.DataType import TAB_STR_TOKENERR
64from Library.DataType import TAB_HEX_START
65from Library.DataType import TAB_SPLIT
66import Library.DataType as DT
67from Library.CommentParsing import ParseHeaderCommentSection
68from Library.CommentParsing import ParseGenericComment
69from Library.CommentParsing import ParseDecPcdGenericComment
70from Library.CommentParsing import ParseDecPcdTailComment
71from Library.Misc import GetFiles
72from Library.Misc import Sdict
73from Library.Misc import GetRelativePath
74from Library.Misc import PathClass
75from Library.Misc import ValidateUNIFilePath
76from Library.UniClassObject import UniFileClassObject
77from Library.UniClassObject import ConvertSpecialUnicodes
78from Library.UniClassObject import GetLanguageCode1766
79from Library.ParserValidate import IsValidPath
80from Parser.DecParser import Dec
81from Object.POM.PackageObject import PackageObject
82from Object.POM.CommonObject import UserExtensionObject
83from Object.POM.CommonObject import IncludeObject
84from Object.POM.CommonObject import GuidObject
85from Object.POM.CommonObject import ProtocolObject
86from Object.POM.CommonObject import PpiObject
87from Object.POM.CommonObject import LibraryClassObject
88from Object.POM.CommonObject import PcdObject
89from Object.POM.CommonObject import TextObject
90from Object.POM.CommonObject import MiscFileObject
91from Object.POM.CommonObject import FileObject
92
93
94## DecPomAlignment
95#
96# Inherited from PackageObject
97#
98class DecPomAlignment(PackageObject):
99    def __init__(self, Filename, WorkspaceDir = None, CheckMulDec = False):
100        PackageObject.__init__(self)
101        self.UserExtensions = ''
102        self.WorkspaceDir = WorkspaceDir
103        self.SupArchList = ARCH_LIST
104        self.CheckMulDec = CheckMulDec
105        self.DecParser = None
106        self.UniFileClassObject = None
107        self.PcdDefaultValueDict = {}
108
109        #
110        # Load Dec file
111        #
112        self.LoadDecFile(Filename)
113
114        #
115        # Transfer to Package Object if IsToPackage is True
116        #
117        self.DecToPackage()
118
119    ## Load Dec file
120    #
121    # Load the file if it exists
122    #
123    # @param Filename:  Input value for filename of Dec file
124    #
125    def LoadDecFile(self, Filename):
126        #
127        # Insert a record for file
128        #
129        Filename = NormPath(Filename)
130        (Path, Name) = os.path.split(Filename)
131        self.SetFullPath(Filename)
132        self.SetRelaPath(Path)
133        self.SetFileName(Name)
134        self.SetPackagePath(GetRelativePath(Path, self.WorkspaceDir))
135        self.SetCombinePath(GetRelativePath(Filename, self.WorkspaceDir))
136
137        self.DecParser = Dec(Filename)
138
139    ## Transfer to Package Object
140    #
141    # Transfer all contents of a Dec file to a standard Package Object
142    #
143    def DecToPackage(self):
144        #
145        # Init global information for the file
146        #
147        ContainerFile = self.GetFullPath()
148
149        #
150        # Generate Package Header
151        #
152        self.GenPackageHeader(ContainerFile)
153
154        #
155        # Generate Includes
156        #
157        self.GenIncludes(ContainerFile)
158
159        #
160        # Generate Guids
161        #
162        self.GenGuidProtocolPpis(TAB_GUIDS, ContainerFile)
163
164        #
165        # Generate Protocols
166        #
167        self.GenGuidProtocolPpis(TAB_PROTOCOLS, ContainerFile)
168
169        #
170        # Generate Ppis
171        #
172        self.GenGuidProtocolPpis(TAB_PPIS, ContainerFile)
173
174        #
175        # Generate LibraryClasses
176        #
177        self.GenLibraryClasses(ContainerFile)
178
179        #
180        # Generate Pcds
181        #
182        self.GenPcds(ContainerFile)
183
184        #
185        # Generate Module File list, will be used later on to generate
186        # distribution
187        #
188        self.GenModuleFileList(ContainerFile)
189
190        #
191        # Generate user extensions
192        #
193        self.GenUserExtensions()
194
195    ## Generate user extension
196    #
197    #
198    def GenUserExtensions(self):
199        UEObj = self.DecParser.GetUserExtensionSectionObject()
200        UEList = UEObj.GetAllUserExtensions()
201        for Item in UEList:
202            if not Item.UserString:
203                continue
204            UserExtension = UserExtensionObject()
205            UserId = Item.UserId
206            if UserId.startswith('"') and UserId.endswith('"'):
207                UserId = UserId[1:-1]
208            UserExtension.SetUserID(UserId)
209            Identifier = Item.IdString
210            if Identifier.startswith('"') and Identifier.endswith('"'):
211                Identifier = Identifier[1:-1]
212            #
213            # Generate miscellaneous files of DEC file
214            #
215            if UserId == 'TianoCore' and Identifier == 'ExtraFiles':
216                self.GenMiscFiles(Item.UserString)
217            UserExtension.SetIdentifier(Identifier)
218            UserExtension.SetStatement(Item.UserString)
219            UserExtension.SetSupArchList(
220                Item.ArchAndModuleType
221            )
222            self.SetUserExtensionList(
223                self.GetUserExtensionList() + [UserExtension]
224            )
225
226        # Add Private sections to UserExtension
227        if self.DecParser.GetPrivateSections():
228            PrivateUserExtension = UserExtensionObject()
229            PrivateUserExtension.SetStatement(self.DecParser.GetPrivateSections())
230            PrivateUserExtension.SetIdentifier(DT.TAB_PRIVATE)
231            PrivateUserExtension.SetUserID(DT.TAB_INTEL)
232            self.SetUserExtensionList(self.GetUserExtensionList() + [PrivateUserExtension])
233
234    ## Generate miscellaneous files on DEC file
235    #
236    #
237    def GenMiscFiles(self, Content):
238        MiscFileObj = MiscFileObject()
239        for Line in Content.splitlines():
240            FileName = ''
241            if '#' in Line:
242                FileName = Line[:Line.find('#')]
243            else:
244                FileName = Line
245            if FileName:
246                if IsValidPath(FileName, self.GetRelaPath()):
247                    FileObj = FileObject()
248                    FileObj.SetURI(FileName)
249                    MiscFileObj.SetFileList(MiscFileObj.GetFileList()+[FileObj])
250                else:
251                    Logger.Error("InfParser",
252                                 FORMAT_INVALID,
253                                 ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID%(Line),
254                                 File=self.GetFileName(),
255                                 ExtraData=Line)
256        self.SetMiscFileList(self.GetMiscFileList()+[MiscFileObj])
257
258    ## Generate Package Header
259    #
260    # Gen Package Header of Dec as <Key> = <Value>
261    #
262    # @param ContainerFile: The Dec file full path
263    #
264    def GenPackageHeader(self, ContainerFile):
265        Logger.Debug(2, "Generate PackageHeader ...")
266        DefinesDict = {}
267
268        #
269        # Update all defines item in database
270        #
271        DefObj = self.DecParser.GetDefineSectionObject()
272        for Item in DefObj.GetDefines():
273            #
274            # put items into Dict except for PackageName, Guid, Version, DEC_SPECIFICATION
275            #
276            SkipItemList = [TAB_DEC_DEFINES_PACKAGE_NAME, \
277                TAB_DEC_DEFINES_PACKAGE_GUID, TAB_DEC_DEFINES_PACKAGE_VERSION, \
278                TAB_DEC_DEFINES_DEC_SPECIFICATION, TAB_DEC_DEFINES_PKG_UNI_FILE]
279            if Item.Key in SkipItemList:
280                continue
281            DefinesDict['%s = %s' % (Item.Key, Item.Value)] = TAB_ARCH_COMMON
282
283        self.SetBaseName(DefObj.GetPackageName())
284        self.SetVersion(DefObj.GetPackageVersion())
285#        self.SetName(DefObj.GetPackageName() + ' Version ' + \
286#                     DefObj.GetPackageVersion())
287        self.SetName(os.path.splitext(self.GetFileName())[0])
288        self.SetGuid(DefObj.GetPackageGuid())
289        if DefObj.GetPackageUniFile():
290            ValidateUNIFilePath(DefObj.GetPackageUniFile())
291            self.UniFileClassObject = \
292            UniFileClassObject([PathClass(os.path.join(DefObj.GetPackagePath(), DefObj.GetPackageUniFile()))])
293        else:
294            self.UniFileClassObject = None
295
296        if DefinesDict:
297            UserExtension = UserExtensionObject()
298            UserExtension.SetDefinesDict(DefinesDict)
299            UserExtension.SetIdentifier('DefineModifiers')
300            UserExtension.SetUserID('EDK2')
301            self.SetUserExtensionList(
302                self.GetUserExtensionList() + [UserExtension]
303            )
304
305        #
306        # Get File header information
307        #
308        if self.UniFileClassObject:
309            Lang = TAB_LANGUAGE_EN_X
310        else:
311            Lang = TAB_LANGUAGE_EN_US
312        Abstract, Description, Copyright, License = \
313            ParseHeaderCommentSection(self.DecParser.GetHeadComment(),
314                                      ContainerFile)
315        if Abstract:
316            self.SetAbstract((Lang, Abstract))
317        if Description:
318            self.SetDescription((Lang, Description))
319        if Copyright:
320            self.SetCopyright(('', Copyright))
321        if License:
322            self.SetLicense(('', License))
323
324        #
325        # Get Binary header information
326        #
327        if self.DecParser.BinaryHeadComment:
328            Abstract, Description, Copyright, License = \
329                ParseHeaderCommentSection(self.DecParser.BinaryHeadComment,
330                                      ContainerFile, True)
331
332            if not Abstract  or not Description or not Copyright or not License:
333                Logger.Error('MkPkg',
334                             FORMAT_INVALID,
335                             ST.ERR_INVALID_BINARYHEADER_FORMAT,
336                             ContainerFile)
337            else:
338                self.SetBinaryHeaderAbstract((Lang, Abstract))
339                self.SetBinaryHeaderDescription((Lang, Description))
340                self.SetBinaryHeaderCopyright(('', Copyright))
341                self.SetBinaryHeaderLicense(('', License))
342
343        BinaryAbstractList = []
344        BinaryDescriptionList = []
345
346        #Get Binary header from UNI file
347        # Initialize the UniStrDict dictionary, top keys are language codes
348        UniStrDict = {}
349        if self.UniFileClassObject:
350            UniStrDict = self.UniFileClassObject.OrderedStringList
351            for Lang in UniStrDict:
352                for StringDefClassObject in UniStrDict[Lang]:
353                    Lang = GetLanguageCode1766(Lang)
354                    if StringDefClassObject.StringName == TAB_DEC_BINARY_ABSTRACT:
355                        if (Lang, ConvertSpecialUnicodes(StringDefClassObject.StringValue)) \
356                        not in self.GetBinaryHeaderAbstract():
357                            BinaryAbstractList.append((Lang, ConvertSpecialUnicodes(StringDefClassObject.StringValue)))
358                    if StringDefClassObject.StringName == TAB_DEC_BINARY_DESCRIPTION:
359                        if (Lang, ConvertSpecialUnicodes(StringDefClassObject.StringValue)) \
360                        not in self.GetBinaryHeaderDescription():
361                            BinaryDescriptionList.append((Lang,
362                                                          ConvertSpecialUnicodes(StringDefClassObject.StringValue)))
363        #Combine Binary header from DEC file and UNI file
364        BinaryAbstractList = self.GetBinaryHeaderAbstract() + BinaryAbstractList
365        BinaryDescriptionList = self.GetBinaryHeaderDescription() + BinaryDescriptionList
366        BinaryCopyrightList = self.GetBinaryHeaderCopyright()
367        BinaryLicenseList = self.GetBinaryHeaderLicense()
368        #Generate the UserExtensionObject for TianoCore."BinaryHeader"
369        if BinaryAbstractList or BinaryDescriptionList or BinaryCopyrightList or BinaryLicenseList:
370            BinaryUserExtension = UserExtensionObject()
371            BinaryUserExtension.SetBinaryAbstract(BinaryAbstractList)
372            BinaryUserExtension.SetBinaryDescription(BinaryDescriptionList)
373            BinaryUserExtension.SetBinaryCopyright(BinaryCopyrightList)
374            BinaryUserExtension.SetBinaryLicense(BinaryLicenseList)
375            BinaryUserExtension.SetIdentifier(TAB_BINARY_HEADER_IDENTIFIER)
376            BinaryUserExtension.SetUserID(TAB_BINARY_HEADER_USERID)
377            self.SetUserExtensionList(self.GetUserExtensionList() + [BinaryUserExtension])
378
379
380    ## GenIncludes
381    #
382    # Gen Includes of Dec
383    #
384    # @param ContainerFile: The Dec file full path
385    #
386    def GenIncludes(self, ContainerFile):
387        if ContainerFile:
388            pass
389        Logger.Debug(2, "Generate %s ..." % TAB_INCLUDES)
390        IncludesDict = Sdict()
391
392        IncObj = self.DecParser.GetIncludeSectionObject()
393        for Item in IncObj.GetAllIncludes():
394            IncludePath = os.path.normpath(Item.File)
395            if platform.system() != 'Windows' and platform.system() != 'Microsoft':
396                IncludePath = IncludePath.replace('\\', '/')
397            if IncludePath in IncludesDict:
398                if Item.GetArchList() == [TAB_ARCH_COMMON] or IncludesDict[IncludePath] == [TAB_ARCH_COMMON]:
399                    IncludesDict[IncludePath] = [TAB_ARCH_COMMON]
400                else:
401                    IncludesDict[IncludePath] = IncludesDict[IncludePath] + Item.GetArchList()
402            else:
403                IncludesDict[IncludePath] = Item.GetArchList()
404
405        #
406        # get the  standardIncludeFileList(industry), packageIncludeFileList
407        # (others) for PackageObject
408        #
409        PackagePath = os.path.split(self.GetFullPath())[0]
410        IncludePathList = \
411            [os.path.normpath(Path) + sep for Path in IncludesDict.keys()]
412        IncludePathList.sort()
413
414        #
415        # get a non-overlap set of include path, IncludePathList should be
416        # sorted, and path should be end with path seperator '\'
417        #
418        NonOverLapList = []
419        for Path1 in IncludePathList:
420            for Path2 in NonOverLapList:
421                if Path1.startswith(Path2):
422                    break
423            else:
424                NonOverLapList.append(Path1)
425        #
426        # revert the list so the longest path shown first in list, also need
427        # to remove the extra path seperator '\'
428        # as this list is used to search the supported Arch info
429        #
430        for IndexN in range (0, len(IncludePathList)):
431            IncludePathList[IndexN] = os.path.normpath(IncludePathList[IndexN])
432        IncludePathList.sort()
433        IncludePathList.reverse()
434        #
435        # save the include path list for later usage
436        #
437        self.SetIncludePathList(IncludePathList)
438        StandardIncludeFileList = []
439        PackageIncludeFileList = []
440
441        IncludeFileList = []
442        for Path in NonOverLapList:
443            FileList = GetFiles(os.path.join(PackagePath, Path), ['CVS', '.svn'], False)
444            IncludeFileList += [os.path.normpath(os.path.join(Path, File)) for File in FileList]
445        for Includefile in IncludeFileList:
446            ExtName = os.path.splitext(Includefile)[1]
447            if ExtName.upper() == '.DEC' and self.CheckMulDec:
448                Logger.Error('MkPkg',
449                             UPT_MUL_DEC_ERROR,
450                             ST.ERR_MUL_DEC_ERROR%(os.path.dirname(ContainerFile),
451                                                   os.path.basename(ContainerFile),
452                                                   Includefile))
453
454            FileCombinePath = os.path.dirname(Includefile)
455            Include = IncludeObject()
456            for Path in IncludePathList:
457                if FileCombinePath.startswith(Path):
458                    SupArchList = IncludesDict[Path]
459                    break
460            Include.SetFilePath(Includefile)
461            Include.SetSupArchList(SupArchList)
462            if Includefile.find('IndustryStandard') != -1:
463                StandardIncludeFileList.append(Include)
464            else:
465                PackageIncludeFileList.append(Include)
466
467        self.SetStandardIncludeFileList(StandardIncludeFileList)
468
469        #
470        # put include path into the PackageIncludeFileList
471        #
472        PackagePathList = []
473        IncObj = self.DecParser.GetIncludeSectionObject()
474        for Item in IncObj.GetAllIncludes():
475            IncludePath = Item.File
476            Include = IncludeObject()
477            Include.SetFilePath(IncludePath)
478            Include.SetSupArchList(Item.GetArchList())
479            PackagePathList.append(Include)
480        self.SetPackageIncludeFileList(PackagePathList + PackageIncludeFileList)
481
482    ## GenPpis
483    #
484    # Gen Ppis of Dec
485    # <CName>=<GuidValue>
486    #
487    # @param ContainerFile: The Dec file full path
488    #
489    def GenGuidProtocolPpis(self, Type, ContainerFile):
490        if ContainerFile:
491            pass
492        Logger.Debug(2, "Generate %s ..." % Type)
493
494        Obj = None
495        Factory = None
496        if Type == TAB_GUIDS:
497            Obj = self.DecParser.GetGuidSectionObject()
498            def CreateGuidObject():
499                Object = GuidObject()
500                Object.SetGuidTypeList([])
501                Object.SetUsage(None)
502                Object.SetName(None)
503                return Object
504            Factory = CreateGuidObject
505        elif Type == TAB_PROTOCOLS:
506            Obj = self.DecParser.GetProtocolSectionObject()
507
508            def CreateProtocolObject():
509                return ProtocolObject()
510            Factory = CreateProtocolObject
511        elif Type == TAB_PPIS:
512            Obj = self.DecParser.GetPpiSectionObject()
513
514            def CreatePpiObject():
515                return PpiObject()
516            Factory = CreatePpiObject
517        else:
518            #
519            # Should not be here
520            #
521            return
522
523        DeclarationsList = []
524
525        #
526        # Go through each arch
527        #
528        for Item in Obj.GetGuidStyleAllItems():
529            Name = Item.GuidCName
530            Value = Item.GuidString
531            HelpTxt = ParseGenericComment(Item.GetHeadComment() + \
532                                          Item.GetTailComment())
533
534            ListObject = Factory()
535            ListObject.SetCName(Name)
536            ListObject.SetGuid(Value)
537            ListObject.SetSupArchList(Item.GetArchList())
538            if HelpTxt:
539                if self.UniFileClassObject:
540                    HelpTxt.SetLang(TAB_LANGUAGE_EN_X)
541                ListObject.SetHelpTextList([HelpTxt])
542
543            DeclarationsList.append(ListObject)
544
545        #
546        #GuidTypeList is abstracted from help
547        #
548        if Type == TAB_GUIDS:
549            self.SetGuidList(self.GetGuidList() + DeclarationsList)
550        elif Type == TAB_PROTOCOLS:
551            self.SetProtocolList(self.GetProtocolList() + DeclarationsList)
552        elif Type == TAB_PPIS:
553            self.SetPpiList(self.GetPpiList() + DeclarationsList)
554
555    ## GenLibraryClasses
556    #
557    # Gen LibraryClasses of Dec
558    # <CName>=<GuidValue>
559    #
560    # @param ContainerFile: The Dec file full path
561    #
562    def GenLibraryClasses(self, ContainerFile):
563        if ContainerFile:
564            pass
565        Logger.Debug(2, "Generate %s ..." % TAB_LIBRARY_CLASSES)
566        LibraryClassDeclarations = []
567
568        LibObj = self.DecParser.GetLibraryClassSectionObject()
569        for Item in LibObj.GetAllLibraryclasses():
570            LibraryClass = LibraryClassObject()
571            LibraryClass.SetLibraryClass(Item.Libraryclass)
572            LibraryClass.SetSupArchList(Item.GetArchList())
573            LibraryClass.SetIncludeHeader(Item.File)
574            HelpTxt = ParseGenericComment(Item.GetHeadComment() + \
575                                          Item.GetTailComment(), None, '@libraryclass')
576            if HelpTxt:
577                if self.UniFileClassObject:
578                    HelpTxt.SetLang(TAB_LANGUAGE_EN_X)
579                LibraryClass.SetHelpTextList([HelpTxt])
580            LibraryClassDeclarations.append(LibraryClass)
581
582        self.SetLibraryClassList(self.GetLibraryClassList() + \
583                                 LibraryClassDeclarations)
584
585    ## GenPcds
586    #
587    # Gen Pcds of Dec
588    # <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
589    #
590    # @param ContainerFile: The Dec file full path
591    #
592    def GenPcds(self, ContainerFile):
593        Logger.Debug(2, "Generate %s ..." % TAB_PCDS)
594        PcdObj = self.DecParser.GetPcdSectionObject()
595        #
596        # Get all Pcds
597        #
598        PcdDeclarations = []
599        IterList = [
600            (TAB_PCDS_FIXED_AT_BUILD_NULL,      'FixedPcd'),
601            (TAB_PCDS_PATCHABLE_IN_MODULE_NULL, 'PatchPcd'),
602            (TAB_PCDS_FEATURE_FLAG_NULL,        'FeaturePcd'),
603            (TAB_PCDS_DYNAMIC_EX_NULL,          'PcdEx'),
604            (TAB_PCDS_DYNAMIC_NULL,             'Pcd')]
605
606        PromptStrList = []
607        HelpStrList = []
608        PcdErrStrList = []
609        # Initialize UniStrDict dictionary, top keys are language codes
610        UniStrDict = {}
611        StrList = []
612
613        Language = ''
614        if self.UniFileClassObject:
615            Language = TAB_LANGUAGE_EN_X
616        else:
617            Language = TAB_LANGUAGE_EN_US
618
619        if self.UniFileClassObject:
620            UniStrDict = self.UniFileClassObject.OrderedStringList
621            for Lang in UniStrDict:
622                for StringDefClassObject in UniStrDict[Lang]:
623                    StrList = StringDefClassObject.StringName.split('_')
624                    # StringName format is STR_<TOKENSPACECNAME>_<PCDCNAME>_PROMPT
625                    if len(StrList) == 4 and StrList[0] == TAB_STR_TOKENCNAME and StrList[3] == TAB_STR_TOKENPROMPT:
626                        PromptStrList.append((GetLanguageCode1766(Lang), StringDefClassObject.StringName, \
627                                              StringDefClassObject.StringValue))
628                    # StringName format is STR_<TOKENSPACECNAME>_<PCDCNAME>_HELP
629                    if len(StrList) == 4 and StrList[0] == TAB_STR_TOKENCNAME and StrList[3] == TAB_STR_TOKENHELP:
630                        HelpStrList.append((GetLanguageCode1766(Lang), StringDefClassObject.StringName, \
631                                            StringDefClassObject.StringValue))
632                    # StringName format is STR_<TOKENSPACECNAME>_ERR_##
633                    if len(StrList) == 4 and StrList[0] == TAB_STR_TOKENCNAME and StrList[2] == TAB_STR_TOKENERR:
634                        PcdErrStrList.append((GetLanguageCode1766(Lang), StringDefClassObject.StringName, \
635                                              StringDefClassObject.StringValue))
636        #
637        # For each PCD type
638        #
639        for PcdType, Type in IterList:
640            #
641            # Go through all archs
642            #
643            # for Arch in self.SupArchList + [TAB_ARCH_COMMON]:
644            #
645            for Item in PcdObj.GetPcdsByType(PcdType.upper()):
646                PcdDeclaration = GenPcdDeclaration(
647                        ContainerFile,
648                        (Item.TokenSpaceGuidCName, Item.TokenCName,
649                        Item.DefaultValue, Item.DatumType, Item.TokenValue,
650                        Type, Item.GetHeadComment(), Item.GetTailComment(),''),
651                        Language,
652                        self.DecParser.GetDefineSectionMacro()
653                        )
654                PcdDeclaration.SetSupArchList(Item.GetArchListOfType(PcdType))
655
656                #
657                # Get PCD error message from PCD error comment section in DEC file
658                #
659                for PcdErr in PcdDeclaration.GetPcdErrorsList():
660                    if (PcdDeclaration.GetTokenSpaceGuidCName(), PcdErr.GetErrorNumber()) \
661                        in self.DecParser.PcdErrorCommentDict:
662                        Key = (PcdDeclaration.GetTokenSpaceGuidCName(), PcdErr.GetErrorNumber())
663                        PcdErr.SetErrorMessageList(PcdErr.GetErrorMessageList() + \
664                                                      [(Language, self.DecParser.PcdErrorCommentDict[Key])])
665
666                for Index in range(0, len(PromptStrList)):
667                    StrNameList = PromptStrList[Index][1].split('_')
668                    if StrNameList[1].lower() == Item.TokenSpaceGuidCName.lower() and \
669                    StrNameList[2].lower() == Item.TokenCName.lower():
670                        TxtObj = TextObject()
671                        TxtObj.SetLang(PromptStrList[Index][0])
672                        TxtObj.SetString(PromptStrList[Index][2])
673                        for Prompt in PcdDeclaration.GetPromptList():
674                            if Prompt.GetLang() == TxtObj.GetLang() and \
675                                Prompt.GetString() == TxtObj.GetString():
676                                break
677                        else:
678                            PcdDeclaration.SetPromptList(PcdDeclaration.GetPromptList() + [TxtObj])
679
680                for Index in range(0, len(HelpStrList)):
681                    StrNameList = HelpStrList[Index][1].split('_')
682                    if StrNameList[1].lower() == Item.TokenSpaceGuidCName.lower() and \
683                    StrNameList[2].lower() == Item.TokenCName.lower():
684                        TxtObj = TextObject()
685                        TxtObj.SetLang(HelpStrList[Index][0])
686                        TxtObj.SetString(HelpStrList[Index][2])
687                        for HelpStrObj in PcdDeclaration.GetHelpTextList():
688                            if HelpStrObj.GetLang() == TxtObj.GetLang() and \
689                                HelpStrObj.GetString() == TxtObj.GetString():
690                                break
691                        else:
692                            PcdDeclaration.SetHelpTextList(PcdDeclaration.GetHelpTextList() + [TxtObj])
693
694                #
695                # Get PCD error message from UNI file
696                #
697                for Index in range(0, len(PcdErrStrList)):
698                    StrNameList = PcdErrStrList[Index][1].split('_')
699                    if StrNameList[1].lower() == Item.TokenSpaceGuidCName.lower() and \
700                        StrNameList[2].lower() == TAB_STR_TOKENERR.lower():
701                        for PcdErr in PcdDeclaration.GetPcdErrorsList():
702                            if PcdErr.GetErrorNumber().lower() == (TAB_HEX_START + StrNameList[3]).lower() and \
703                                (PcdErrStrList[Index][0], PcdErrStrList[Index][2]) not in PcdErr.GetErrorMessageList():
704                                PcdErr.SetErrorMessageList(PcdErr.GetErrorMessageList() + \
705                                                            [(PcdErrStrList[Index][0], PcdErrStrList[Index][2])])
706
707                #
708                # Check to prevent missing error message if a Pcd has the error code.
709                #
710                for PcdErr in PcdDeclaration.GetPcdErrorsList():
711                    if PcdErr.GetErrorNumber().strip():
712                        if not PcdErr.GetErrorMessageList():
713                            Logger.Error('UPT',
714                                         FORMAT_INVALID,
715                                         ST.ERR_DECPARSE_PCD_UNMATCHED_ERRORCODE % PcdErr.GetErrorNumber(),
716                                         ContainerFile,
717                                         PcdErr.GetLineNum(),
718                                         PcdErr.GetFileLine())
719
720                PcdDeclarations.append(PcdDeclaration)
721        self.SetPcdList(self.GetPcdList() + PcdDeclarations)
722        self.CheckPcdValue()
723
724    ##
725    # Get error message via language
726    # @param ErrorMessageList: Error message tuple list the language and its message
727    # @param Lang: the language of setting
728    # @return: the error message described in the related UNI file
729    def GetEnErrorMessage(self, ErrorMessageList):
730        if self.FullPath:
731            pass
732        Lang = TAB_LANGUAGE_EN_US
733        for (Language, Message) in ErrorMessageList:
734            if Language == Lang:
735                return Message
736        for (Language, Message) in ErrorMessageList:
737            if Language.find(TAB_LANGUAGE_EN) >= 0:
738                return Message
739        else:
740            try:
741                return ErrorMessageList[0][1]
742            except IndexError:
743                return ''
744        return ''
745
746    ##
747    # Replace the strings for Python eval function.
748    # @param ReplaceValue: The string that needs to be replaced.
749    # @return: The string was replaced, then eval function is always making out it.
750    def ReplaceForEval(self, ReplaceValue, IsRange=False, IsExpr=False):
751        if self.FullPath:
752            pass
753        #
754        # deal with "NOT EQ", "NOT LT", "NOT GT", "NOT LE", "NOT GE", "NOT NOT"
755        #
756        NOTNOT_Pattern = '[\t\s]*NOT[\t\s]+NOT[\t\s]*'
757        NOTGE_Pattern = '[\t\s]*NOT[\t\s]+GE[\t\s]*'
758        NOTLE_Pattern = '[\t\s]*NOT[\t\s]+LE[\t\s]*'
759        NOTGT_Pattern = '[\t\s]*NOT[\t\s]+GT[\t\s]*'
760        NOTLT_Pattern = '[\t\s]*NOT[\t\s]+LT[\t\s]*'
761        NOTEQ_Pattern = '[\t\s]*NOT[\t\s]+EQ[\t\s]*'
762        ReplaceValue = re.compile(NOTNOT_Pattern).sub('', ReplaceValue)
763        ReplaceValue = re.compile(NOTLT_Pattern).sub('x >= ', ReplaceValue)
764        ReplaceValue = re.compile(NOTGT_Pattern).sub('x <= ', ReplaceValue)
765        ReplaceValue = re.compile(NOTLE_Pattern).sub('x > ', ReplaceValue)
766        ReplaceValue = re.compile(NOTGE_Pattern).sub('x < ', ReplaceValue)
767        ReplaceValue = re.compile(NOTEQ_Pattern).sub('x != ', ReplaceValue)
768
769        if IsRange:
770            ReplaceValue = ReplaceValue.replace('EQ', 'x ==')
771            ReplaceValue = ReplaceValue.replace('LT', 'x <')
772            ReplaceValue = ReplaceValue.replace('LE', 'x <=')
773            ReplaceValue = ReplaceValue.replace('GT', 'x >')
774            ReplaceValue = ReplaceValue.replace('GE', 'x >=')
775            ReplaceValue = ReplaceValue.replace('XOR', 'x ^')
776        elif IsExpr:
777            ReplaceValue = ReplaceValue.replace('EQ', '==')
778            ReplaceValue = ReplaceValue.replace('NE', '!=')
779            ReplaceValue = ReplaceValue.replace('LT', '<')
780            ReplaceValue = ReplaceValue.replace('LE', '<=')
781            ReplaceValue = ReplaceValue.replace('GT', '>')
782            ReplaceValue = ReplaceValue.replace('GE', '>=')
783            ReplaceValue = ReplaceValue.replace('XOR', '^')
784
785        ReplaceValue = ReplaceValue.replace('AND', 'and')
786        ReplaceValue = ReplaceValue.replace('&&', ' and ')
787        ReplaceValue = ReplaceValue.replace('xor', '^')
788        ReplaceValue = ReplaceValue.replace('OR', 'or')
789        ReplaceValue = ReplaceValue.replace('||', ' or ')
790        ReplaceValue = ReplaceValue.replace('NOT', 'not')
791        if ReplaceValue.find('!') >= 0 and ReplaceValue[ReplaceValue.index('!') + 1] != '=':
792            ReplaceValue = ReplaceValue.replace('!', ' not ')
793        if '.' in ReplaceValue:
794            Pattern = '[a-zA-Z0-9]{1,}\.[a-zA-Z0-9]{1,}'
795            MatchedList = re.findall(Pattern, ReplaceValue)
796            for MatchedItem in MatchedList:
797                if MatchedItem not in self.PcdDefaultValueDict:
798                    Logger.Error("Dec File Parser", FORMAT_INVALID, Message=ST.ERR_DECPARSE_PCD_NODEFINED % MatchedItem,
799                                     File=self.FullPath)
800
801                ReplaceValue = ReplaceValue.replace(MatchedItem, self.PcdDefaultValueDict[MatchedItem])
802
803        return ReplaceValue
804
805    ##
806    # Check pcd's default value according to the pcd's description
807    #
808    def CheckPcdValue(self):
809        for Pcd in self.GetPcdList():
810            self.PcdDefaultValueDict[TAB_SPLIT.join((Pcd.GetTokenSpaceGuidCName(), Pcd.GetCName())).strip()] = \
811            Pcd.GetDefaultValue()
812
813        for Pcd in self.GetPcdList():
814            ValidationExpressions = []
815            PcdGuidName = TAB_SPLIT.join((Pcd.GetTokenSpaceGuidCName(), Pcd.GetCName()))
816            Valids = Pcd.GetPcdErrorsList()
817            for Valid in Valids:
818                Expression = Valid.GetExpression()
819                if Expression:
820                    #
821                    # Delete the 'L' prefix of a quoted string, this operation is for eval()
822                    #
823                    QUOTED_PATTERN = '[\t\s]*L?"[^"]*"'
824                    QuotedMatchedObj = re.search(QUOTED_PATTERN, Expression)
825                    if QuotedMatchedObj:
826                        MatchedStr = QuotedMatchedObj.group().strip()
827                        if MatchedStr.startswith('L'):
828                            Expression = Expression.replace(MatchedStr, MatchedStr[1:].strip())
829
830                    Expression = self.ReplaceForEval(Expression, IsExpr=True)
831                    Expression = Expression.replace(PcdGuidName, 'x')
832                    Message = self.GetEnErrorMessage(Valid.GetErrorMessageList())
833                    ValidationExpressions.append((Expression, Message))
834
835                ValidList = Valid.GetValidValue()
836                if ValidList:
837                    ValidValue = 'x in %s' % [eval(v) for v in ValidList.split(' ') if v]
838                    Message = self.GetEnErrorMessage(Valid.GetErrorMessageList())
839                    ValidationExpressions.append((ValidValue, Message))
840
841                ValidValueRange = Valid.GetValidValueRange()
842                if ValidValueRange:
843                    ValidValueRange = self.ReplaceForEval(ValidValueRange, IsRange=True)
844                    if ValidValueRange.find('-') >= 0:
845                        ValidValueRange = ValidValueRange.replace('-', '<= x <=')
846                    elif not ValidValueRange.startswith('x ') and not ValidValueRange.startswith('not ') \
847                        and not ValidValueRange.startswith('not(') and not ValidValueRange.startswith('('):
848                        ValidValueRange = 'x %s' % ValidValueRange
849                    Message = self.GetEnErrorMessage(Valid.GetErrorMessageList())
850                    ValidationExpressions.append((ValidValueRange, Message))
851
852            DefaultValue = self.PcdDefaultValueDict[PcdGuidName.strip()]
853            #
854            # Delete the 'L' prefix of a quoted string, this operation is for eval()
855            #
856            QUOTED_PATTERN = '[\t\s]*L?"[^"]*"'
857            QuotedMatchedObj = re.search(QUOTED_PATTERN, DefaultValue)
858            if QuotedMatchedObj:
859                MatchedStr = QuotedMatchedObj.group().strip()
860                if MatchedStr.startswith('L'):
861                    DefaultValue = DefaultValue.replace(MatchedStr, MatchedStr[1:].strip())
862
863            try:
864                DefaultValue = eval(DefaultValue.replace('TRUE', 'True').replace('true', 'True')
865                                        .replace('FALSE', 'False').replace('false', 'False'))
866            except BaseException:
867                pass
868
869            for (Expression, Msg) in ValidationExpressions:
870                try:
871                    if not eval(Expression, {'x':DefaultValue}):
872                        Logger.Error("Dec File Parser", FORMAT_INVALID, ExtraData='%s, value = %s' %\
873                                     (PcdGuidName, DefaultValue), Message=Msg, File=self.FullPath)
874                except TypeError:
875                    Logger.Error("Dec File Parser", FORMAT_INVALID, ExtraData=PcdGuidName, \
876                                    Message=Msg, File=self.FullPath)
877
878    ## GenModuleFileList
879    #
880    def GenModuleFileList(self, ContainerFile):
881        ModuleFileList = []
882        ContainerFileName = os.path.basename(ContainerFile)
883        ContainerFilePath = os.path.dirname(ContainerFile)
884        for Item in GetFiles(ContainerFilePath,
885                        ['CVS', '.svn'] + self.GetIncludePathList(), False):
886            ExtName = os.path.splitext(Item)[1]
887            if ExtName.lower() == '.inf':
888                ModuleFileList.append(Item)
889            elif ExtName.upper() == '.DEC' and self.CheckMulDec:
890                if Item == ContainerFileName:
891                    continue
892                Logger.Error('MkPkg',
893                             UPT_MUL_DEC_ERROR,
894                             ST.ERR_MUL_DEC_ERROR%(ContainerFilePath,
895                                                   ContainerFileName,
896                                                   Item))
897
898        self.SetModuleFileList(ModuleFileList)
899
900    ## Show detailed information of Package
901    #
902    # Print all members and their values of Package class
903    #
904    def ShowPackage(self):
905        print '\nName =', self.GetName()
906        print '\nBaseName =', self.GetBaseName()
907        print '\nVersion =', self.GetVersion()
908        print '\nGuid =', self.GetGuid()
909
910        print '\nStandardIncludes = %d ' \
911            % len(self.GetStandardIncludeFileList()),
912        for Item in self.GetStandardIncludeFileList():
913            print Item.GetFilePath(), '  ', Item.GetSupArchList()
914        print '\nPackageIncludes = %d \n' \
915            % len(self.GetPackageIncludeFileList()),
916        for Item in self.GetPackageIncludeFileList():
917            print Item.GetFilePath(), '  ', Item.GetSupArchList()
918
919        print '\nGuids =', self.GetGuidList()
920        for Item in self.GetGuidList():
921            print Item.GetCName(), Item.GetGuid(), Item.GetSupArchList()
922        print '\nProtocols =', self.GetProtocolList()
923        for Item in self.GetProtocolList():
924            print Item.GetCName(), Item.GetGuid(), Item.GetSupArchList()
925        print '\nPpis =', self.GetPpiList()
926        for Item in self.GetPpiList():
927            print Item.GetCName(), Item.GetGuid(), Item.GetSupArchList()
928        print '\nLibraryClasses =', self.GetLibraryClassList()
929        for Item in self.GetLibraryClassList():
930            print Item.GetLibraryClass(), Item.GetRecommendedInstance(), \
931            Item.GetSupArchList()
932        print '\nPcds =', self.GetPcdList()
933        for Item in self.GetPcdList():
934            print 'CName=', Item.GetCName(), 'TokenSpaceGuidCName=', \
935                Item.GetTokenSpaceGuidCName(), \
936                'DefaultValue=', Item.GetDefaultValue(), \
937                'ValidUsage=', Item.GetValidUsage(), \
938                'SupArchList', Item.GetSupArchList(), \
939                'Token=', Item.GetToken(), 'DatumType=', Item.GetDatumType()
940
941        for Item in self.GetMiscFileList():
942            print Item.GetName()
943            for FileObjectItem in Item.GetFileList():
944                print FileObjectItem.GetURI()
945        print '****************\n'
946
947## GenPcdDeclaration
948#
949# @param ContainerFile:   File name of the DEC file
950# @param PcdInfo:         Pcd information, of format (TokenGuidCName,
951#                         TokenName, Value, DatumType, Token, Type,
952#                         GenericComment, TailComment, Arch)
953# @param Language: The language of HelpText, Prompt
954#
955def GenPcdDeclaration(ContainerFile, PcdInfo, Language, MacroReplaceDict):
956    HelpStr = ''
957    PromptStr = ''
958    TailHelpStr = ''
959    TokenGuidCName, TokenName, Value, DatumType, Token, Type, \
960        GenericComment, TailComment, Arch = PcdInfo
961    Pcd = PcdObject()
962    Pcd.SetCName(TokenName)
963    Pcd.SetToken(Token)
964    Pcd.SetTokenSpaceGuidCName(TokenGuidCName)
965    Pcd.SetDatumType(DatumType)
966    Pcd.SetDefaultValue(Value)
967    Pcd.SetValidUsage(Type)
968    #
969    #  MaxDatumSize is required field for 'VOID*' PCD
970    #
971    if DatumType == TAB_PTR_TYPE_PCD:
972        Pcd.SetMaxDatumSize(ITEM_UNDEFINED)
973
974    SupArchList = [Arch]
975    Pcd.SetSupArchList(SupArchList)
976
977    if GenericComment:
978        HelpStr, PcdErrList, PromptStr = ParseDecPcdGenericComment(GenericComment,
979                                                                   ContainerFile,
980                                                                   TokenGuidCName,
981                                                                   TokenName,
982                                                                   MacroReplaceDict)
983        if PcdErrList:
984            Pcd.SetPcdErrorsList(PcdErrList)
985
986    if TailComment:
987        SupModuleList, TailHelpStr = ParseDecPcdTailComment(TailComment,
988                                                        ContainerFile)
989        if SupModuleList:
990            Pcd.SetSupModuleList(SupModuleList)
991
992    if HelpStr and (not HelpStr.endswith('\n')) and TailHelpStr:
993        HelpStr += '\n'
994    HelpStr += TailHelpStr
995    if HelpStr:
996        HelpTxtObj = TextObject()
997        HelpTxtObj.SetLang(Language)
998        HelpTxtObj.SetString(HelpStr)
999        Pcd.SetHelpTextList([HelpTxtObj])
1000    if PromptStr:
1001        TxtObj = TextObject()
1002        TxtObj.SetLang(Language)
1003        TxtObj.SetString(PromptStr)
1004        Pcd.SetPromptList([TxtObj])
1005
1006    return Pcd
1007