• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1## @file GenDecFile.py
2#
3# This file contained the logical of transfer package object to DEC files.
4#
5# Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
6#
7# This program and the accompanying materials are licensed and made available
8# under the terms and conditions of the BSD License which accompanies this
9# distribution. The full text of the license may be found at
10# http://opensource.org/licenses/bsd-license.php
11#
12# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14#
15
16'''
17GenDEC
18'''
19import os
20import stat
21import codecs
22import md5
23from Core.FileHook import __FileHookOpen__
24from Library.Parsing import GenSection
25from Library.CommentGenerating import GenHeaderCommentSection
26from Library.CommentGenerating import GenGenericCommentF
27from Library.CommentGenerating import GenDecTailComment
28from Library.CommentGenerating import _GetHelpStr
29from Library.Misc import GuidStringToGuidStructureString
30from Library.Misc import SaveFileOnChange
31from Library.Misc import ConvertPath
32from Library.Misc import GetLocalValue
33from Library.DataType import TAB_SPACE_SPLIT
34from Library.DataType import TAB_COMMA_SPLIT
35from Library.DataType import END_OF_LINE
36from Library.DataType import TAB_ARCH_COMMON
37from Library.DataType import TAB_VALUE_SPLIT
38from Library.DataType import TAB_COMMENT_SPLIT
39from Library.DataType import TAB_PCD_VALIDRANGE
40from Library.DataType import TAB_PCD_VALIDLIST
41from Library.DataType import TAB_PCD_EXPRESSION
42from Library.DataType import TAB_DEC_DEFINES_DEC_SPECIFICATION
43from Library.DataType import TAB_DEC_DEFINES_PACKAGE_NAME
44from Library.DataType import TAB_DEC_DEFINES_PACKAGE_GUID
45from Library.DataType import TAB_DEC_DEFINES_PACKAGE_VERSION
46from Library.DataType import TAB_DEC_DEFINES_PKG_UNI_FILE
47from Library.DataType import TAB_DEC_PACKAGE_ABSTRACT
48from Library.DataType import TAB_DEC_PACKAGE_DESCRIPTION
49from Library.DataType import TAB_DEC_BINARY_ABSTRACT
50from Library.DataType import TAB_DEC_BINARY_DESCRIPTION
51from Library.DataType import TAB_LANGUAGE_EN_X
52from Library.DataType import TAB_BINARY_HEADER_USERID
53from Library.DataType import TAB_BINARY_HEADER_IDENTIFIER
54from Library.DataType import TAB_COMMENT_EDK1_SPLIT
55from Library.DataType import TAB_ENCODING_UTF16LE
56from Library.DataType import TAB_CAPHEX_START
57from Library.DataType import TAB_HEX_START
58from Library.DataType import TAB_UNDERLINE_SPLIT
59from Library.DataType import TAB_STR_TOKENERR
60from Library.DataType import TAB_STR_TOKENCNAME
61from Library.DataType import TAB_PCD_ERROR_SECTION_COMMENT
62from Library.DataType import TAB_PCD_ERROR
63from Library.DataType import TAB_SECTION_START
64from Library.DataType import TAB_SECTION_END
65from Library.DataType import TAB_SPLIT
66import Library.DataType as DT
67from Library.UniClassObject import FormatUniEntry
68from Library.String import GetUniFileName
69
70def GenPcd(Package, Content):
71    #
72    # generate [Pcd] section
73    # <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
74    #
75    ValidUsageDict = {}
76    for Pcd in Package.GetPcdList():
77        #
78        # Generate generic comment
79        #
80        HelpTextList = Pcd.GetHelpTextList()
81        HelpStr = _GetHelpStr(HelpTextList)
82        CommentStr = GenGenericCommentF(HelpStr, 2)
83
84        PromptList = Pcd.GetPromptList()
85        PromptStr = _GetHelpStr(PromptList)
86        CommentStr += GenGenericCommentF(PromptStr.strip(), 1, True)
87
88        PcdErrList = Pcd.GetPcdErrorsList()
89        for PcdErr in PcdErrList:
90            CommentStr += GenPcdErrComment(PcdErr)
91        Statement = CommentStr
92
93        CName = Pcd.GetCName()
94        TokenSpaceGuidCName = Pcd.GetTokenSpaceGuidCName()
95        DefaultValue = Pcd.GetDefaultValue()
96        DatumType = Pcd.GetDatumType()
97        Token = Pcd.GetToken()
98        ValidUsage = Pcd.GetValidUsage()
99
100        if ValidUsage == 'FeaturePcd':
101            ValidUsage = 'PcdsFeatureFlag'
102        elif ValidUsage == 'PatchPcd':
103            ValidUsage = 'PcdsPatchableInModule'
104        elif ValidUsage == 'FixedPcd':
105            ValidUsage = 'PcdsFixedAtBuild'
106        elif ValidUsage == 'Pcd':
107            ValidUsage = 'PcdsDynamic'
108        elif ValidUsage == 'PcdEx':
109            ValidUsage = 'PcdsDynamicEx'
110
111        if ValidUsage in ValidUsageDict:
112            NewSectionDict = ValidUsageDict[ValidUsage]
113        else:
114            NewSectionDict = {}
115            ValidUsageDict[ValidUsage] = NewSectionDict
116        Statement += TokenSpaceGuidCName + '.' + CName
117        Statement += '|' + DefaultValue
118        Statement += '|' + DatumType
119        Statement += '|' + Token
120        #
121        # generate tail comment
122        #
123        if Pcd.GetSupModuleList():
124            Statement += GenDecTailComment(Pcd.GetSupModuleList())
125
126        ArchList = Pcd.GetSupArchList()
127        ArchList.sort()
128        SortedArch = ' '.join(ArchList)
129        if SortedArch in NewSectionDict:
130            NewSectionDict[SortedArch] = \
131            NewSectionDict[SortedArch] + [Statement]
132        else:
133            NewSectionDict[SortedArch] = [Statement]
134
135    for ValidUsage in ValidUsageDict:
136        Content += GenSection(ValidUsage, ValidUsageDict[ValidUsage], True, True)
137
138    return Content
139
140def GenPcdErrorMsgSection(Package, Content):
141    if not Package.PcdErrorCommentDict:
142        return Content
143
144    #
145    # Generate '# [Error.<TokenSpcCName>]' section
146    #
147    Content += END_OF_LINE + END_OF_LINE
148    SectionComment = TAB_COMMENT_SPLIT + END_OF_LINE
149    SectionComment += TAB_COMMENT_SPLIT + TAB_SPACE_SPLIT + TAB_PCD_ERROR_SECTION_COMMENT + END_OF_LINE
150    SectionComment += TAB_COMMENT_SPLIT + END_OF_LINE
151    TokenSpcCNameList = []
152
153    #
154    # Get TokenSpcCName list in PcdErrorCommentDict in Package object
155    #
156    for (TokenSpcCName, ErrorNumber) in Package.PcdErrorCommentDict:
157        if TokenSpcCName not in TokenSpcCNameList:
158            TokenSpcCNameList.append(TokenSpcCName)
159
160    for TokenSpcCNameItem in TokenSpcCNameList:
161        SectionName = TAB_COMMENT_SPLIT + TAB_SPACE_SPLIT + TAB_SECTION_START + TAB_PCD_ERROR + \
162                      TAB_SPLIT + TokenSpcCNameItem + TAB_SECTION_END + END_OF_LINE
163        Content += SectionComment
164        Content += SectionName
165        for (TokenSpcCName, ErrorNumber) in Package.PcdErrorCommentDict:
166            if TokenSpcCNameItem == TokenSpcCName:
167                PcdErrorMsg = GetLocalValue(Package.PcdErrorCommentDict[(TokenSpcCName, ErrorNumber)])
168                SectionItem = TAB_COMMENT_SPLIT + TAB_SPACE_SPLIT + TAB_SPACE_SPLIT + \
169                              ErrorNumber + TAB_SPACE_SPLIT + TAB_VALUE_SPLIT + TAB_SPACE_SPLIT + \
170                              PcdErrorMsg + END_OF_LINE
171                Content += SectionItem
172
173    Content += TAB_COMMENT_SPLIT
174    return Content
175
176def GenGuidProtocolPpi(Package, Content):
177    #
178    # generate [Guids] section
179    #
180    NewSectionDict = {}
181
182    LeftOffset = 46
183    # Get the line offset need
184    # If the real one < the min one, use the min one
185    # else use the real one
186    for Guid in Package.GetGuidList():
187        if len(Guid.GetCName()) > LeftOffset:
188            LeftOffset = len(Guid.GetCName())
189
190    # Generate
191    for Guid in Package.GetGuidList():
192        #
193        # Generate generic comment
194        #
195        HelpTextList = Guid.GetHelpTextList()
196        HelpStr = _GetHelpStr(HelpTextList)
197        CommentStr = GenGenericCommentF(HelpStr, 2)
198
199        Statement = CommentStr
200        CName = Guid.GetCName()
201        Value = GuidStringToGuidStructureString(Guid.GetGuid())
202        Statement += CName.ljust(LeftOffset) + ' = ' + Value
203        #
204        # generate tail comment
205        #
206        if Guid.GetSupModuleList():
207            Statement += GenDecTailComment(Guid.GetSupModuleList())
208        ArchList = Guid.GetSupArchList()
209        ArchList.sort()
210        SortedArch = ' '.join(ArchList)
211        if SortedArch in NewSectionDict:
212            NewSectionDict[SortedArch] = \
213            NewSectionDict[SortedArch] + [Statement]
214        else:
215            NewSectionDict[SortedArch] = [Statement]
216
217    Content += GenSection('Guids', NewSectionDict, True, True)
218
219    #
220    # generate [Protocols] section
221    #
222    NewSectionDict = {}
223    LeftOffset = 46
224    # Get the line offset need
225    # If the real one < the min one, use the min one
226    # else use the real one
227    for Protocol in Package.GetProtocolList():
228        if len(Protocol.GetCName()) > LeftOffset:
229            LeftOffset = len(Protocol.GetCName())
230
231    for Protocol in Package.GetProtocolList():
232        #
233        # Generate generic comment
234        #
235        HelpTextList = Protocol.GetHelpTextList()
236        HelpStr = _GetHelpStr(HelpTextList)
237        CommentStr = GenGenericCommentF(HelpStr, 2)
238
239        Statement = CommentStr
240        CName = Protocol.GetCName()
241        Value = GuidStringToGuidStructureString(Protocol.GetGuid())
242        Statement += CName.ljust(LeftOffset) + ' = ' + Value
243
244        #
245        # generate tail comment
246        #
247        if Protocol.GetSupModuleList():
248            Statement += GenDecTailComment(Protocol.GetSupModuleList())
249        ArchList = Protocol.GetSupArchList()
250        ArchList.sort()
251        SortedArch = ' '.join(ArchList)
252        if SortedArch in NewSectionDict:
253            NewSectionDict[SortedArch] = \
254            NewSectionDict[SortedArch] + [Statement]
255        else:
256            NewSectionDict[SortedArch] = [Statement]
257
258    Content += GenSection('Protocols', NewSectionDict, True, True)
259
260    #
261    # generate [Ppis] section
262    #
263    NewSectionDict = {}
264    LeftOffset = 46
265    # Get the line offset need
266    # If the real one < the min one, use the min one
267    # else use the real one
268    for Ppi in Package.GetPpiList():
269        if len(Ppi.GetCName()) > LeftOffset:
270            LeftOffset = len(Ppi.GetCName())
271
272    for Ppi in Package.GetPpiList():
273        #
274        # Generate generic comment
275        #
276        HelpTextList = Ppi.GetHelpTextList()
277        HelpStr = _GetHelpStr(HelpTextList)
278        CommentStr = GenGenericCommentF(HelpStr, 2)
279
280        Statement = CommentStr
281        CName = Ppi.GetCName()
282        Value = GuidStringToGuidStructureString(Ppi.GetGuid())
283        Statement += CName.ljust(LeftOffset) + ' = ' + Value
284
285        #
286        # generate tail comment
287        #
288        if Ppi.GetSupModuleList():
289            Statement += GenDecTailComment(Ppi.GetSupModuleList())
290        ArchList = Ppi.GetSupArchList()
291        ArchList.sort()
292        SortedArch = ' '.join(ArchList)
293        if SortedArch in NewSectionDict:
294            NewSectionDict[SortedArch] = \
295            NewSectionDict[SortedArch] + [Statement]
296        else:
297            NewSectionDict[SortedArch] = [Statement]
298
299    Content += GenSection('Ppis', NewSectionDict, True, True)
300
301    return Content
302
303## Transfer Package Object to Dec files
304#
305# Transfer all contents of a standard Package Object to a Dec file
306#
307# @param Package:  A Package
308#
309def PackageToDec(Package, DistHeader = None):
310    #
311    # Init global information for the file
312    #
313    ContainerFile = Package.GetFullPath()
314
315    Content = ''
316
317    #
318    # Generate file header
319    #
320    PackageAbstract = GetLocalValue(Package.GetAbstract())
321    PackageDescription = GetLocalValue(Package.GetDescription())
322    PackageCopyright = ''
323    PackageLicense = ''
324    for (Lang, Copyright) in Package.GetCopyright():
325        if Lang:
326            pass
327        PackageCopyright = Copyright
328    for (Lang, License) in Package.GetLicense():
329        if Lang:
330            pass
331        PackageLicense = License
332    if not PackageAbstract and DistHeader:
333        PackageAbstract = GetLocalValue(DistHeader.GetAbstract())
334    if not PackageDescription and DistHeader:
335        PackageDescription = GetLocalValue(DistHeader.GetDescription())
336    if not PackageCopyright and DistHeader:
337        for (Lang, Copyright) in DistHeader.GetCopyright():
338            PackageCopyright = Copyright
339    if not PackageLicense and DistHeader:
340        for (Lang, License) in DistHeader.GetLicense():
341            PackageLicense = License
342
343    #
344    # Generate header comment section of DEC file
345    #
346    Content += GenHeaderCommentSection(PackageAbstract, \
347                                       PackageDescription, \
348                                       PackageCopyright, \
349                                       PackageLicense).replace('\r\n', '\n')
350
351    #
352    # Generate Binary header
353    #
354    for UserExtension in Package.GetUserExtensionList():
355        if UserExtension.GetUserID() == TAB_BINARY_HEADER_USERID \
356        and UserExtension.GetIdentifier() == TAB_BINARY_HEADER_IDENTIFIER:
357            PackageBinaryAbstract = GetLocalValue(UserExtension.GetBinaryAbstract())
358            PackageBinaryDescription = GetLocalValue(UserExtension.GetBinaryDescription())
359            PackageBinaryCopyright = ''
360            PackageBinaryLicense = ''
361            for (Lang, Copyright) in UserExtension.GetBinaryCopyright():
362                PackageBinaryCopyright = Copyright
363            for (Lang, License) in UserExtension.GetBinaryLicense():
364                PackageBinaryLicense = License
365            if PackageBinaryAbstract and PackageBinaryDescription and \
366            PackageBinaryCopyright and PackageBinaryLicense:
367                Content += GenHeaderCommentSection(PackageBinaryAbstract,
368                                           PackageBinaryDescription,
369                                           PackageBinaryCopyright,
370                                           PackageBinaryLicense,
371                                           True)
372
373    #
374    # Generate PACKAGE_UNI_FILE for the Package
375    #
376    FileHeader = GenHeaderCommentSection(PackageAbstract, PackageDescription, PackageCopyright, PackageLicense, False, \
377                                         TAB_COMMENT_EDK1_SPLIT)
378    GenPackageUNIEncodeFile(Package, FileHeader)
379
380    #
381    # for each section, maintain a dict, sorted arch will be its key,
382    #statement list will be its data
383    # { 'Arch1 Arch2 Arch3': [statement1, statement2],
384    #   'Arch1' : [statement1, statement3]
385    #  }
386    #
387
388    #
389    # generate [Defines] section
390    #
391    LeftOffset = 31
392    NewSectionDict = {TAB_ARCH_COMMON : []}
393    SpecialItemList = []
394
395    Statement = (u'%s ' % TAB_DEC_DEFINES_DEC_SPECIFICATION).ljust(LeftOffset) + u'= %s' % '0x00010017'
396    SpecialItemList.append(Statement)
397
398    BaseName = Package.GetBaseName()
399    if BaseName.startswith('.') or BaseName.startswith('-'):
400        BaseName = '_' + BaseName
401    Statement = (u'%s ' % TAB_DEC_DEFINES_PACKAGE_NAME).ljust(LeftOffset) + u'= %s' % BaseName
402    SpecialItemList.append(Statement)
403
404    Statement = (u'%s ' % TAB_DEC_DEFINES_PACKAGE_VERSION).ljust(LeftOffset) + u'= %s' % Package.GetVersion()
405    SpecialItemList.append(Statement)
406
407    Statement = (u'%s ' % TAB_DEC_DEFINES_PACKAGE_GUID).ljust(LeftOffset) + u'= %s' % Package.GetGuid()
408    SpecialItemList.append(Statement)
409
410    if Package.UNIFlag:
411        Statement = (u'%s ' % TAB_DEC_DEFINES_PKG_UNI_FILE).ljust(LeftOffset) + u'= %s' % Package.GetBaseName() + '.uni'
412        SpecialItemList.append(Statement)
413
414    for SortedArch in NewSectionDict:
415        NewSectionDict[SortedArch] = \
416        NewSectionDict[SortedArch] + SpecialItemList
417    Content += GenSection('Defines', NewSectionDict)
418
419    #
420    # generate [Includes] section
421    #
422    NewSectionDict = {}
423    IncludeArchList = Package.GetIncludeArchList()
424    if IncludeArchList:
425        for Path, ArchList in IncludeArchList:
426            Statement = Path
427            ArchList.sort()
428            SortedArch = ' '.join(ArchList)
429            if SortedArch in NewSectionDict:
430                NewSectionDict[SortedArch] = \
431                NewSectionDict[SortedArch] + [ConvertPath(Statement)]
432            else:
433                NewSectionDict[SortedArch] = [ConvertPath(Statement)]
434
435    Content += GenSection('Includes', NewSectionDict)
436
437    #
438    # generate [guids][protocols][ppis] sections
439    #
440    Content = GenGuidProtocolPpi(Package, Content)
441
442    #
443    # generate [LibraryClasses] section
444    #
445    NewSectionDict = {}
446    for LibraryClass in Package.GetLibraryClassList():
447        #
448        # Generate generic comment
449        #
450        HelpTextList = LibraryClass.GetHelpTextList()
451        HelpStr = _GetHelpStr(HelpTextList)
452        if HelpStr:
453            HelpStr = '@libraryclass' + HelpStr
454        CommentStr = GenGenericCommentF(HelpStr, 2, False, True)
455
456        Statement = CommentStr
457        Name = LibraryClass.GetLibraryClass()
458        IncludeHeader = LibraryClass.GetIncludeHeader()
459        Statement += Name + '|' + ConvertPath(IncludeHeader)
460        #
461        # generate tail comment
462        #
463        if LibraryClass.GetSupModuleList():
464            Statement += \
465            GenDecTailComment(LibraryClass.GetSupModuleList())
466        ArchList = LibraryClass.GetSupArchList()
467        ArchList.sort()
468        SortedArch = ' '.join(ArchList)
469        if SortedArch in NewSectionDict:
470            NewSectionDict[SortedArch] = \
471            NewSectionDict[SortedArch] + [Statement]
472        else:
473            NewSectionDict[SortedArch] = [Statement]
474
475    Content += GenSection('LibraryClasses', NewSectionDict, True, True)
476
477    #
478    # Generate '# [Error.<TokenSpcCName>]' section
479    #
480    Content = GenPcdErrorMsgSection(Package, Content)
481
482    Content = GenPcd(Package, Content)
483
484    #
485    # generate [UserExtensions] section
486    #
487    NewSectionDict = {}
488    for UserExtension in Package.GetUserExtensionList():
489        if UserExtension.GetUserID() == TAB_BINARY_HEADER_USERID and \
490            UserExtension.GetIdentifier() == TAB_BINARY_HEADER_IDENTIFIER:
491            continue
492
493        # Generate Private Section first
494        if UserExtension.GetUserID() == DT.TAB_INTEL and UserExtension.GetIdentifier() == DT.TAB_PRIVATE:
495            Content += '\n' + UserExtension.GetStatement()
496            continue
497
498        Statement = UserExtension.GetStatement()
499        if not Statement:
500            continue
501        else:
502            LineList = Statement.split('\n')
503            NewStatement = ""
504            for Line in LineList:
505                NewStatement += "  %s\n" % Line
506
507        SectionList = []
508        SectionName = 'UserExtensions'
509        UserId = UserExtension.GetUserID()
510        if UserId:
511            if '.' in UserId:
512                UserId = '"' + UserId + '"'
513            SectionName += '.' + UserId
514            if UserExtension.GetIdentifier():
515                SectionName += '.' + '"' + UserExtension.GetIdentifier() + '"'
516        if not UserExtension.GetSupArchList():
517            SectionList.append(SectionName)
518        else:
519            for Arch in UserExtension.GetSupArchList():
520                SectionList.append(SectionName + '.' + Arch)
521        SectionName = ', '.join(SectionList)
522        SectionName = ''.join(['[', SectionName, ']\n'])
523        Content += '\n' + SectionName + NewStatement
524
525    SaveFileOnChange(ContainerFile, Content, False)
526    if DistHeader.ReadOnly:
527        os.chmod(ContainerFile, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH)
528    else:
529        os.chmod(ContainerFile, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH|stat.S_IWUSR|stat.S_IWGRP|stat.S_IWOTH)
530    return ContainerFile
531
532## GenPackageUNIEncodeFile
533# GenPackageUNIEncodeFile, default is a UCS-2LE encode file
534#
535def GenPackageUNIEncodeFile(PackageObject, UniFileHeader = '', Encoding=TAB_ENCODING_UTF16LE):
536    GenUNIFlag = False
537    OnlyLANGUAGE_EN_X = True
538    BinaryAbstract = []
539    BinaryDescription = []
540    #
541    # If more than one language code is used for any element that would be present in the PACKAGE_UNI_FILE,
542    # then the PACKAGE_UNI_FILE must be created.
543    #
544    for (Key, Value) in PackageObject.GetAbstract() + PackageObject.GetDescription():
545        if Key == TAB_LANGUAGE_EN_X:
546            GenUNIFlag = True
547        else:
548            OnlyLANGUAGE_EN_X = False
549
550    for UserExtension in PackageObject.GetUserExtensionList():
551        if UserExtension.GetUserID() == TAB_BINARY_HEADER_USERID \
552        and UserExtension.GetIdentifier() == TAB_BINARY_HEADER_IDENTIFIER:
553            for (Key, Value) in UserExtension.GetBinaryAbstract():
554                if Key == TAB_LANGUAGE_EN_X:
555                    GenUNIFlag = True
556                else:
557                    OnlyLANGUAGE_EN_X = False
558                BinaryAbstract.append((Key, Value))
559
560            for (Key, Value) in UserExtension.GetBinaryDescription():
561                if Key == TAB_LANGUAGE_EN_X:
562                    GenUNIFlag = True
563                else:
564                    OnlyLANGUAGE_EN_X = False
565                BinaryDescription.append((Key, Value))
566
567    for Pcd in PackageObject.GetPcdList():
568        for TxtObj in Pcd.GetPromptList() + Pcd.GetHelpTextList():
569            if TxtObj.GetLang() == TAB_LANGUAGE_EN_X:
570                GenUNIFlag = True
571            else:
572                OnlyLANGUAGE_EN_X = False
573
574        for PcdError in Pcd.GetPcdErrorsList():
575            if PcdError.GetErrorNumber().startswith('0x') or PcdError.GetErrorNumber().startswith('0X'):
576                for (Key, Value) in PcdError.GetErrorMessageList():
577                    if Key == TAB_LANGUAGE_EN_X:
578                        GenUNIFlag = True
579                    else:
580                        OnlyLANGUAGE_EN_X = False
581    if not GenUNIFlag:
582        return
583    elif OnlyLANGUAGE_EN_X:
584        return
585    else:
586        PackageObject.UNIFlag = True
587
588    if not os.path.exists(os.path.dirname(PackageObject.GetFullPath())):
589        os.makedirs(os.path.dirname(PackageObject.GetFullPath()))
590
591    ContainerFile = GetUniFileName(os.path.dirname(PackageObject.GetFullPath()), PackageObject.GetBaseName())
592
593    Content = UniFileHeader + '\r\n'
594    Content += '\r\n'
595
596    Content += FormatUniEntry('#string ' + TAB_DEC_PACKAGE_ABSTRACT, PackageObject.GetAbstract(), ContainerFile) + '\r\n'
597
598    Content += FormatUniEntry('#string ' + TAB_DEC_PACKAGE_DESCRIPTION, PackageObject.GetDescription(), ContainerFile) \
599    + '\r\n'
600
601    Content += FormatUniEntry('#string ' + TAB_DEC_BINARY_ABSTRACT, BinaryAbstract, ContainerFile) + '\r\n'
602
603    Content += FormatUniEntry('#string ' + TAB_DEC_BINARY_DESCRIPTION, BinaryDescription, ContainerFile) + '\r\n'
604
605    PromptGenList = []
606    HelpTextGenList = []
607    for Pcd in PackageObject.GetPcdList():
608        # Generate Prompt for each Pcd
609        PcdPromptStrName = '#string ' + 'STR_' + Pcd.GetTokenSpaceGuidCName() + '_' + Pcd.GetCName() + '_PROMPT '
610        TokenValueList = []
611        for TxtObj in Pcd.GetPromptList():
612            Lang = TxtObj.GetLang()
613            PromptStr = TxtObj.GetString()
614            #
615            # Avoid generating the same PROMPT entry more than one time.
616            #
617            if (PcdPromptStrName, Lang) not in PromptGenList:
618                TokenValueList.append((Lang, PromptStr))
619                PromptGenList.append((PcdPromptStrName, Lang))
620        PromptString = FormatUniEntry(PcdPromptStrName, TokenValueList, ContainerFile) + '\r\n'
621        if PromptString not in Content:
622            Content += PromptString
623
624        # Generate Help String for each Pcd
625        PcdHelpStrName = '#string ' + 'STR_' + Pcd.GetTokenSpaceGuidCName() + '_' + Pcd.GetCName() + '_HELP '
626        TokenValueList = []
627        for TxtObj in Pcd.GetHelpTextList():
628            Lang = TxtObj.GetLang()
629            HelpStr = TxtObj.GetString()
630            #
631            # Avoid generating the same HELP entry more than one time.
632            #
633            if (PcdHelpStrName, Lang) not in HelpTextGenList:
634                TokenValueList.append((Lang, HelpStr))
635                HelpTextGenList.append((PcdHelpStrName, Lang))
636        HelpTextString = FormatUniEntry(PcdHelpStrName, TokenValueList, ContainerFile) + '\r\n'
637        if HelpTextString not in Content:
638            Content += HelpTextString
639
640        # Generate PcdError for each Pcd if ErrorNo exist.
641        for PcdError in Pcd.GetPcdErrorsList():
642            ErrorNo = PcdError.GetErrorNumber()
643            if ErrorNo.startswith(TAB_HEX_START) or ErrorNo.startswith(TAB_CAPHEX_START):
644                PcdErrStrName = '#string ' + TAB_STR_TOKENCNAME + TAB_UNDERLINE_SPLIT + Pcd.GetTokenSpaceGuidCName() \
645                    + TAB_UNDERLINE_SPLIT + TAB_STR_TOKENERR \
646                    + TAB_UNDERLINE_SPLIT + ErrorNo[2:]
647                PcdErrString = FormatUniEntry(PcdErrStrName, PcdError.GetErrorMessageList(), ContainerFile) + '\r\n'
648                if PcdErrString not in Content:
649                    Content += PcdErrString
650
651    File = codecs.open(ContainerFile, 'w', Encoding)
652    File.write(u'\uFEFF' + Content)
653    File.stream.close()
654    Md5Sigature = md5.new(__FileHookOpen__(str(ContainerFile), 'rb').read())
655    Md5Sum = Md5Sigature.hexdigest()
656    if (ContainerFile, Md5Sum) not in PackageObject.FileList:
657        PackageObject.FileList.append((ContainerFile, Md5Sum))
658
659    return ContainerFile
660
661## GenPcdErrComment
662#
663#  @param PcdErrObject:  PcdErrorObject
664#
665#  @retval CommentStr:   Generated comment lines, with prefix "#"
666#
667def GenPcdErrComment (PcdErrObject):
668    CommentStr = ''
669    ErrorCode = PcdErrObject.GetErrorNumber()
670    ValidValueRange = PcdErrObject.GetValidValueRange()
671    if ValidValueRange:
672        CommentStr = TAB_COMMENT_SPLIT + TAB_SPACE_SPLIT + TAB_PCD_VALIDRANGE + TAB_SPACE_SPLIT
673        if ErrorCode:
674            CommentStr += ErrorCode + TAB_SPACE_SPLIT + TAB_VALUE_SPLIT + TAB_SPACE_SPLIT
675        CommentStr += ValidValueRange + END_OF_LINE
676
677    ValidValue = PcdErrObject.GetValidValue()
678    if ValidValue:
679        ValidValueList = \
680        [Value for Value in ValidValue.split(TAB_SPACE_SPLIT) if Value]
681        CommentStr = TAB_COMMENT_SPLIT + TAB_SPACE_SPLIT + TAB_PCD_VALIDLIST + TAB_SPACE_SPLIT
682        if ErrorCode:
683            CommentStr += ErrorCode + TAB_SPACE_SPLIT + TAB_VALUE_SPLIT + TAB_SPACE_SPLIT
684        CommentStr += TAB_COMMA_SPLIT.join(ValidValueList) + END_OF_LINE
685
686    Expression = PcdErrObject.GetExpression()
687    if Expression:
688        CommentStr = TAB_COMMENT_SPLIT + TAB_SPACE_SPLIT + TAB_PCD_EXPRESSION + TAB_SPACE_SPLIT
689        if ErrorCode:
690            CommentStr += ErrorCode + TAB_SPACE_SPLIT + TAB_VALUE_SPLIT + TAB_SPACE_SPLIT
691        CommentStr += Expression + END_OF_LINE
692
693    return CommentStr
694
695