1## @file
2# This file is used to define class objects of INF file [Pcds] section.
3# It will consumed by InfParser.
4#
5# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
6#
7# SPDX-License-Identifier: BSD-2-Clause-Patent
8
9'''
10InfPcdObject
11'''
12import os
13import re
14
15from Logger import StringTable as ST
16from Logger import ToolError
17import Logger.Log as Logger
18from Library import GlobalData
19from Library import DataType as DT
20
21from Library.Misc import Sdict
22from Library.Misc import GetHelpStringByRemoveHashKey
23from Library.ParserValidate import IsValidPcdType
24from Library.ParserValidate import IsValidCVariableName
25from Library.ParserValidate import IsValidPcdValue
26from Library.ParserValidate import IsValidArch
27from Library.CommentParsing import ParseComment
28from Library.StringUtils import GetSplitValueList
29from Library.StringUtils import IsHexDigitUINT32
30from Library.ExpressionValidate import IsValidFeatureFlagExp
31from Parser.InfAsBuiltProcess import GetPackageListInfo
32from Parser.DecParser import Dec
33
34from Object.Parser.InfPackagesObject import InfPackageItem
35
36def ValidateArch(ArchItem, PcdTypeItem1, LineNo, SupArchDict, SupArchList):
37    #
38    # Validate Arch
39    #
40    if (ArchItem == '' or ArchItem is None):
41        ArchItem = 'COMMON'
42
43    if PcdTypeItem1.upper != DT.TAB_INF_FEATURE_PCD.upper():
44        ArchList = GetSplitValueList(ArchItem, ' ')
45        for ArchItemNew in ArchList:
46            if not IsValidArch(ArchItemNew):
47                Logger.Error("InfParser",
48                             ToolError.FORMAT_INVALID,
49                             ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID % (ArchItemNew),
50                             File=GlobalData.gINF_MODULE_NAME,
51                             Line=LineNo,
52                             ExtraData=ArchItemNew)
53        SupArchDict[PcdTypeItem1] = ArchList
54    else:
55        SupArchList.append(ArchItem)
56
57    return SupArchList, SupArchDict
58
59def ParsePcdComment(CommentList, PcdTypeItem, PcdItemObj):
60    CommentInsList = []
61    PreUsage = None
62    PreHelpText = ''
63    BlockFlag = -1
64    FFEHelpText = ''
65    CommentItemHelpText = ''
66    Count = 0
67    for CommentItem in CommentList:
68        Count = Count + 1
69        CommentItemUsage, CommentType, CommentString, CommentItemHelpText = ParseComment(CommentItem,
70                                                                             DT.ALL_USAGE_TOKENS,
71                                                                             {},
72                                                                             [],
73                                                                             False)
74        if CommentType and CommentString:
75            pass
76
77        if PcdTypeItem == 'FeaturePcd':
78            CommentItemUsage = DT.USAGE_ITEM_CONSUMES
79            if CommentItemHelpText is None:
80                CommentItemHelpText = ''
81
82            if Count == 1:
83                FFEHelpText = CommentItemHelpText
84            else:
85                FFEHelpText = FFEHelpText + DT.END_OF_LINE + CommentItemHelpText
86
87            if Count == len(CommentList):
88                CommentItemHelpText = FFEHelpText
89                BlockFlag = 4
90            else:
91                continue
92
93        if CommentItemHelpText is None:
94            CommentItemHelpText = ''
95            if Count == len(CommentList) and CommentItemUsage == DT.ITEM_UNDEFINED:
96                CommentItemHelpText = DT.END_OF_LINE
97
98        if Count == len(CommentList) and (BlockFlag == 1 or BlockFlag == 2):
99            if CommentItemUsage == DT.ITEM_UNDEFINED:
100                BlockFlag = 4
101            else:
102                BlockFlag = 3
103        elif BlockFlag == -1 and Count == len(CommentList):
104            BlockFlag = 4
105
106        if BlockFlag == -1 or BlockFlag == 1 or BlockFlag == 2:
107            if CommentItemUsage == DT.ITEM_UNDEFINED:
108                if BlockFlag == -1:
109                    BlockFlag = 1
110                elif BlockFlag == 1:
111                    BlockFlag = 2
112            else:
113                if BlockFlag == 1 or BlockFlag == 2:
114                    BlockFlag = 3
115                elif BlockFlag == -1:
116                    BlockFlag = 4
117        #
118        # Combine two comment line if they are generic comment
119        #
120        if CommentItemUsage == PreUsage == DT.ITEM_UNDEFINED:
121            CommentItemHelpText = PreHelpText + DT.END_OF_LINE + CommentItemHelpText
122
123            PreHelpText = CommentItemHelpText
124
125        if BlockFlag == 4:
126            CommentItemIns = InfPcdItemCommentContent()
127            CommentItemIns.SetUsageItem(CommentItemUsage)
128            CommentItemIns.SetHelpStringItem(CommentItemHelpText)
129            CommentInsList.append(CommentItemIns)
130
131            BlockFlag = -1
132            PreUsage = None
133            PreHelpText = ''
134
135        elif BlockFlag == 3:
136            #
137            # Add previous help string
138            #
139            CommentItemIns = InfPcdItemCommentContent()
140            CommentItemIns.SetUsageItem(DT.ITEM_UNDEFINED)
141            if PreHelpText == '' or PreHelpText.endswith(DT.END_OF_LINE):
142                PreHelpText += DT.END_OF_LINE
143            CommentItemIns.SetHelpStringItem(PreHelpText)
144            CommentInsList.append(CommentItemIns)
145            #
146            # Add Current help string
147            #
148            CommentItemIns = InfPcdItemCommentContent()
149            CommentItemIns.SetUsageItem(CommentItemUsage)
150            CommentItemIns.SetHelpStringItem(CommentItemHelpText)
151            CommentInsList.append(CommentItemIns)
152
153            BlockFlag = -1
154            PreUsage = None
155            PreHelpText = ''
156
157        else:
158            PreUsage = CommentItemUsage
159            PreHelpText = CommentItemHelpText
160
161    PcdItemObj.SetHelpStringList(CommentInsList)
162
163    return PcdItemObj
164
165class InfPcdItemCommentContent():
166    def __init__(self):
167        #
168        # ## SOMETIMES_CONSUMES ## HelpString
169        #
170        self.UsageItem = ''
171        #
172        # Help String
173        #
174        self.HelpStringItem = ''
175
176    def SetUsageItem(self, UsageItem):
177        self.UsageItem = UsageItem
178    def GetUsageItem(self):
179        return self.UsageItem
180
181    def SetHelpStringItem(self, HelpStringItem):
182        self.HelpStringItem = HelpStringItem
183    def GetHelpStringItem(self):
184        return self.HelpStringItem
185
186## InfPcdItem
187#
188# This class defined Pcd item used in Module files
189#
190# @param CName:                Input value for CName, default is ''
191# @param Token:                Input value for Token, default is ''
192# @param TokenSpaceGuidCName:  Input value for TokenSpaceGuidCName, default
193#                              is ''
194# @param DatumType:            Input value for DatumType, default is ''
195# @param MaxDatumSize:         Input value for MaxDatumSize, default is ''
196# @param DefaultValue:         Input value for DefaultValue, default is ''
197# @param ItemType:             Input value for ItemType, default is ''
198# @param ValidUsage:           Input value for ValidUsage, default is []
199# @param SkuInfoList:          Input value for SkuInfoList, default is {}
200# @param SupModuleList:        Input value for SupModuleList, default is []
201#
202class InfPcdItem():
203    def __init__(self):
204        self.CName = ''
205        self.Token = ''
206        self.TokenSpaceGuidCName = ''
207        self.TokenSpaceGuidValue = ''
208        self.DatumType = ''
209        self.MaxDatumSize = ''
210        self.DefaultValue = ''
211        self.Offset = ''
212        self.ValidUsage = ''
213        self.ItemType = ''
214        self.SupModuleList = []
215        self.HelpStringList = []
216        self.FeatureFlagExp = ''
217        self.SupArchList = []
218        self.PcdErrorsList = []
219
220    def SetCName(self, CName):
221        self.CName = CName
222    def GetCName(self):
223        return self.CName
224
225    def SetToken(self, Token):
226        self.Token = Token
227    def GetToken(self):
228        return self.Token
229
230    def SetTokenSpaceGuidCName(self, TokenSpaceGuidCName):
231        self.TokenSpaceGuidCName = TokenSpaceGuidCName
232    def GetTokenSpaceGuidCName(self):
233        return self.TokenSpaceGuidCName
234
235    def SetTokenSpaceGuidValue(self, TokenSpaceGuidValue):
236        self.TokenSpaceGuidValue = TokenSpaceGuidValue
237    def GetTokenSpaceGuidValue(self):
238        return self.TokenSpaceGuidValue
239
240    def SetDatumType(self, DatumType):
241        self.DatumType = DatumType
242    def GetDatumType(self):
243        return self.DatumType
244
245    def SetMaxDatumSize(self, MaxDatumSize):
246        self.MaxDatumSize = MaxDatumSize
247    def GetMaxDatumSize(self):
248        return self.MaxDatumSize
249
250    def SetDefaultValue(self, DefaultValue):
251        self.DefaultValue = DefaultValue
252    def GetDefaultValue(self):
253        return self.DefaultValue
254
255    def SetPcdErrorsList(self, PcdErrorsList):
256        self.PcdErrorsList = PcdErrorsList
257    def GetPcdErrorsList(self):
258        return self.PcdErrorsList
259
260    def SetItemType(self, ItemType):
261        self.ItemType = ItemType
262    def GetItemType(self):
263        return self.ItemType
264
265    def SetSupModuleList(self, SupModuleList):
266        self.SupModuleList = SupModuleList
267    def GetSupModuleList(self):
268        return self.SupModuleList
269
270    def SetHelpStringList(self, HelpStringList):
271        self.HelpStringList = HelpStringList
272    def GetHelpStringList(self):
273        return self.HelpStringList
274
275    def SetFeatureFlagExp(self, FeatureFlagExp):
276        self.FeatureFlagExp = FeatureFlagExp
277    def GetFeatureFlagExp(self):
278        return self.FeatureFlagExp
279
280    def SetSupportArchList(self, ArchList):
281        self.SupArchList = ArchList
282    def GetSupportArchList(self):
283        return self.SupArchList
284
285    def SetOffset(self, Offset):
286        self.Offset = Offset
287    def GetOffset(self):
288        return self.Offset
289
290    def SetValidUsage(self, ValidUsage):
291        self.ValidUsage = ValidUsage
292
293    def GetValidUsage(self):
294        return self.ValidUsage
295
296##
297#
298#
299#
300class InfPcdObject():
301    def __init__(self, FileName):
302        self.Pcds = Sdict()
303        self.FileName = FileName
304
305    def SetPcds(self, PcdContent, KeysList=None, PackageInfo=None):
306
307        if GlobalData.gIS_BINARY_INF:
308            self.SetAsBuildPcds(PcdContent, KeysList, PackageInfo)
309            return True
310
311        #
312        # Validate Arch
313        #
314        SupArchList = []
315        SupArchDict = {}
316        PcdTypeItem = ''
317        for (PcdTypeItem1, ArchItem, LineNo) in KeysList:
318            SupArchList, SupArchDict = ValidateArch(ArchItem, PcdTypeItem1, LineNo, SupArchDict, SupArchList)
319
320            #
321            # Validate PcdType
322            #
323            if (PcdTypeItem1 == '' or PcdTypeItem1 is None):
324                return False
325            else:
326                if not IsValidPcdType(PcdTypeItem1):
327                    Logger.Error("InfParser",
328                                 ToolError.FORMAT_INVALID,
329                                 ST.ERR_INF_PARSER_PCD_SECTION_TYPE_ERROR % (DT.PCD_USAGE_TYPE_LIST_OF_MODULE),
330                                 File=GlobalData.gINF_MODULE_NAME,
331                                 Line=LineNo,
332                                 ExtraData=PcdTypeItem1)
333                    return False
334
335            PcdTypeItem = PcdTypeItem1
336
337            for PcdItem in PcdContent:
338                PcdItemObj = InfPcdItem()
339                CommentList = PcdItem[1]
340                CurrentLineOfPcdItem = PcdItem[2]
341                PcdItem = PcdItem[0]
342
343                if CommentList is not None and len(CommentList) != 0:
344                    PcdItemObj = ParsePcdComment(CommentList, PcdTypeItem, PcdItemObj)
345                else:
346                    CommentItemIns = InfPcdItemCommentContent()
347                    CommentItemIns.SetUsageItem(DT.ITEM_UNDEFINED)
348                    PcdItemObj.SetHelpStringList([CommentItemIns])
349
350                if len(PcdItem) >= 1 and len(PcdItem) <= 3:
351                    PcdItemObj = SetPcdName(PcdItem, CurrentLineOfPcdItem, PcdItemObj)
352
353                if len(PcdItem) >= 2 and len(PcdItem) <= 3:
354                    #
355                    # Contain PcdName and Value, validate value.
356                    #
357                    if IsValidPcdValue(PcdItem[1]) or PcdItem[1].strip() == "":
358                        PcdItemObj.SetDefaultValue(PcdItem[1])
359                    else:
360                        Logger.Error("InfParser",
361                                     ToolError.FORMAT_INVALID,
362                                     ST.ERR_INF_PARSER_PCD_VALUE_INVALID,
363                                     File=CurrentLineOfPcdItem[2],
364                                     Line=CurrentLineOfPcdItem[1],
365                                     ExtraData=PcdItem[1])
366
367                if len(PcdItem) == 3:
368                    #
369                    # Contain PcdName, value, and FeatureFlag express
370                    #
371                    #
372                    # Validate Feature Flag Express
373                    #
374                    if PcdItem[2].strip() == '':
375                        Logger.Error("InfParser",
376                                     ToolError.FORMAT_INVALID,
377                                     ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING,
378                                     File=CurrentLineOfPcdItem[2],
379                                     Line=CurrentLineOfPcdItem[1],
380                                     ExtraData=CurrentLineOfPcdItem[0])
381                    #
382                    # Validate FFE
383                    #
384                    FeatureFlagRtv = IsValidFeatureFlagExp(PcdItem[2].strip())
385                    if not FeatureFlagRtv[0]:
386                        Logger.Error("InfParser",
387                                     ToolError.FORMAT_INVALID,
388                                     ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID % (FeatureFlagRtv[1]),
389                                     File=CurrentLineOfPcdItem[2],
390                                     Line=CurrentLineOfPcdItem[1],
391                                     ExtraData=CurrentLineOfPcdItem[0])
392                    PcdItemObj.SetFeatureFlagExp(PcdItem[2])
393
394                if len(PcdItem) < 1 or len(PcdItem) > 3:
395                    Logger.Error("InfParser",
396                                 ToolError.FORMAT_INVALID,
397                                 ST.ERR_INF_PARSER_PCD_SECTION_CONTENT_ERROR,
398                                 File=CurrentLineOfPcdItem[2],
399                                 Line=CurrentLineOfPcdItem[1],
400                                 ExtraData=CurrentLineOfPcdItem[0])
401                    return False
402
403                if PcdTypeItem.upper != DT.TAB_INF_FEATURE_PCD.upper():
404                    PcdItemObj.SetSupportArchList(SupArchDict[PcdTypeItem])
405                else:
406                    PcdItemObj.SetSupportArchList(SupArchList)
407
408                if (PcdTypeItem, PcdItemObj) in self.Pcds:
409                    PcdsList = self.Pcds[PcdTypeItem, PcdItemObj]
410                    PcdsList.append(PcdItemObj)
411                    self.Pcds[PcdTypeItem, PcdItemObj] = PcdsList
412                else:
413                    PcdsList = []
414                    PcdsList.append(PcdItemObj)
415                    self.Pcds[PcdTypeItem, PcdItemObj] = PcdsList
416
417        return True
418
419    def SetAsBuildPcds(self, PcdContent, KeysList=None, PackageInfo=None):
420        for PcdItem in PcdContent:
421            PcdItemObj = InfPcdItem()
422            CommentList = PcdItem[1]
423            CurrentLineOfPcdItem = PcdItem[2]
424            PcdItem = PcdItem[0]
425            CommentString = ''
426
427            for CommentLine in CommentList:
428                CommentString = GetHelpStringByRemoveHashKey(CommentLine)
429                CommentItemIns = InfPcdItemCommentContent()
430                CommentItemIns.SetHelpStringItem(CommentString)
431                CommentItemIns.SetUsageItem(CommentString)
432                PcdItemObj.SetHelpStringList(PcdItemObj.GetHelpStringList() + [CommentItemIns])
433                if PcdItemObj.GetValidUsage():
434                    PcdItemObj.SetValidUsage(PcdItemObj.GetValidUsage() + DT.TAB_VALUE_SPLIT + CommentString)
435                else:
436                    PcdItemObj.SetValidUsage(CommentString)
437
438            PcdItemObj.SetItemType(KeysList[0][0])
439            #
440            # Set PcdTokenSpaceCName and CName
441            #
442            PcdItemObj = SetPcdName(PcdItem, CurrentLineOfPcdItem, PcdItemObj)
443            #
444            # Set Value/DatumType/OffSet/Token
445            #
446            PcdItemObj = SetValueDatumTypeMaxSizeToken(PcdItem,
447                                                      CurrentLineOfPcdItem,
448                                                      PcdItemObj,
449                                                      KeysList[0][1],
450                                                      PackageInfo)
451
452            PcdTypeItem = KeysList[0][0]
453            if (PcdTypeItem, PcdItemObj) in self.Pcds:
454                PcdsList = self.Pcds[PcdTypeItem, PcdItemObj]
455                PcdsList.append(PcdItemObj)
456                self.Pcds[PcdTypeItem, PcdItemObj] = PcdsList
457            else:
458                PcdsList = []
459                PcdsList.append(PcdItemObj)
460                self.Pcds[PcdTypeItem, PcdItemObj] = PcdsList
461
462    def GetPcds(self):
463        return self.Pcds
464
465def ParserPcdInfoInDec(String):
466    ValueList = GetSplitValueList(String, DT.TAB_VALUE_SPLIT, 3)
467
468    #
469    # DatumType, Token
470    #
471    return ValueList[2], ValueList[3]
472
473def SetValueDatumTypeMaxSizeToken(PcdItem, CurrentLineOfPcdItem, PcdItemObj, Arch, PackageInfo=None):
474    #
475    # Package information not been generated currently, we need to parser INF file to get information.
476    #
477    if not PackageInfo:
478        PackageInfo = []
479        InfFileName = CurrentLineOfPcdItem[2]
480        PackageInfoList = GetPackageListInfo(InfFileName, GlobalData.gWORKSPACE, -1)
481        for PackageInfoListItem in PackageInfoList:
482            PackageInfoIns = InfPackageItem()
483            PackageInfoIns.SetPackageName(PackageInfoListItem)
484            PackageInfo.append(PackageInfoIns)
485
486    PcdInfoInDecHasFound = False
487    for PackageItem in PackageInfo:
488        if PcdInfoInDecHasFound:
489            break
490        PackageName = PackageItem.PackageName
491        #
492        # Open DEC file to get information
493        #
494        FullFileName = os.path.normpath(os.path.realpath(os.path.join(GlobalData.gWORKSPACE, PackageName)))
495
496        DecParser = None
497        if FullFileName not in GlobalData.gPackageDict:
498            DecParser = Dec(FullFileName)
499            GlobalData.gPackageDict[FullFileName] = DecParser
500        else:
501            DecParser = GlobalData.gPackageDict[FullFileName]
502
503        #
504        # Find PCD information.
505        #
506        DecPcdsDict = DecParser.GetPcdSectionObject().ValueDict
507        for Key in DecPcdsDict.keys():
508            if (Key[0] == 'PCDSDYNAMICEX' and PcdItemObj.GetItemType() == 'PcdEx') and \
509                (Key[1] == 'COMMON' or Key[1] == Arch):
510                for PcdInDec in DecPcdsDict[Key]:
511                    if PcdInDec.TokenCName == PcdItemObj.CName and \
512                       PcdInDec.TokenSpaceGuidCName == PcdItemObj.TokenSpaceGuidCName:
513                        PcdItemObj.SetToken(PcdInDec.TokenValue)
514                        PcdItemObj.SetDatumType(PcdInDec.DatumType)
515                        PcdItemObj.SetSupportArchList([Arch])
516                        PcdItemObj.SetDefaultValue(PcdInDec.DefaultValue)
517
518            if (Key[0] == 'PCDSPATCHABLEINMODULE' and PcdItemObj.GetItemType() == 'PatchPcd') and \
519           (Key[1] == 'COMMON' or Key[1] == Arch):
520                for PcdInDec in DecPcdsDict[Key]:
521                    if PcdInDec.TokenCName == PcdItemObj.CName and \
522                       PcdInDec.TokenSpaceGuidCName == PcdItemObj.TokenSpaceGuidCName:
523                        PcdItemObj.SetToken(PcdInDec.TokenValue)
524                        PcdItemObj.SetDatumType(PcdInDec.DatumType)
525                        PcdItemObj.SetSupportArchList([Arch])
526
527        if PcdItemObj.GetDatumType() == 'VOID*':
528            if len(PcdItem) > 1:
529                PcdItemObj.SetMaxDatumSize('%s' % (len(GetSplitValueList(PcdItem[1], DT.TAB_COMMA_SPLIT))))
530
531        DecGuidsDict = DecParser.GetGuidSectionObject().ValueDict
532        for Key in DecGuidsDict.keys():
533            if Key == 'COMMON' or Key == Arch:
534                for GuidInDec in DecGuidsDict[Key]:
535                    if GuidInDec.GuidCName == PcdItemObj.TokenSpaceGuidCName:
536                        PcdItemObj.SetTokenSpaceGuidValue(GuidInDec.GuidString)
537
538    if PcdItemObj.GetItemType().upper() == DT.TAB_INF_PATCH_PCD.upper():
539        #
540        # Validate Value.
541        #
542        # convert the value from a decimal 0 to a formatted hex value.
543        if PcdItem[1] == "0":
544            DatumType = PcdItemObj.GetDatumType()
545            if DatumType == "UINT8":
546                PcdItem[1] = "0x00"
547            if DatumType == "UINT16":
548                PcdItem[1] = "0x0000"
549            if DatumType == "UINT32":
550                PcdItem[1] = "0x00000000"
551            if DatumType == "UINT64":
552                PcdItem[1] = "0x0000000000000000"
553
554        if ValidatePcdValueOnDatumType(PcdItem[1], PcdItemObj.GetDatumType()):
555            PcdItemObj.SetDefaultValue(PcdItem[1])
556        else:
557            Logger.Error("InfParser",
558                     ToolError.FORMAT_INVALID,
559                     ST.ERR_ASBUILD_PCD_VALUE_INVALID % ("\"" + PcdItem[1] + "\"", "\"" +
560                                                       PcdItemObj.GetDatumType() + "\""),
561                     File=CurrentLineOfPcdItem[2],
562                     Line=CurrentLineOfPcdItem[1],
563                     ExtraData=CurrentLineOfPcdItem[0])
564        #
565        # validate offset
566        #
567        if PcdItemObj.GetItemType().upper() == DT.TAB_INF_PATCH_PCD.upper():
568            if not IsHexDigitUINT32(PcdItem[2]):
569                Logger.Error("InfParser",
570                         ToolError.FORMAT_INVALID,
571                         ST.ERR_ASBUILD_PCD_OFFSET_FORMAT_INVALID % ("\"" + PcdItem[2] + "\""),
572                         File=CurrentLineOfPcdItem[2],
573                         Line=CurrentLineOfPcdItem[1],
574                         ExtraData=CurrentLineOfPcdItem[0])
575            PcdItemObj.SetOffset(PcdItem[2])
576
577    if PcdItemObj.GetToken() == '' or PcdItemObj.GetDatumType() == '':
578        Logger.Error("InfParser",
579                     ToolError.FORMAT_INVALID,
580                     ST.ERR_ASBUILD_PCD_DECLARITION_MISS % ("\"" + PcdItem[0] + "\""),
581                     File=CurrentLineOfPcdItem[2],
582                     Line=CurrentLineOfPcdItem[1],
583                     ExtraData=CurrentLineOfPcdItem[0])
584
585    return PcdItemObj
586
587def ValidatePcdValueOnDatumType(Value, Type):
588
589    Value = Value.strip()
590    #
591    # Boolean type only allow 0x00 or 0x01 as value per INF spec
592    #
593    if Type == 'BOOLEAN':
594        if not (Value == '0x00' or Value == '0x01'):
595            return False
596    elif Type == 'VOID*':
597        if not Value.startswith("{"):
598            return False
599        if not Value.endswith("}"):
600            return False
601        #
602        # Strip "{" at head and "}" at tail.
603        #
604        Value = Value[1:-1]
605        ValueList = GetSplitValueList(Value, DT.TAB_COMMA_SPLIT)
606
607        ReIsValidHexByte = re.compile("^0x[0-9a-f]{1,2}$", re.IGNORECASE)
608        for ValueItem in ValueList:
609            if not ReIsValidHexByte.match(ValueItem):
610                return False
611
612    elif Type == 'UINT8' or Type == 'UINT16' or Type == 'UINT32' or Type == 'UINT64':
613
614        ReIsValidUint8z = re.compile('^0[x|X][a-fA-F0-9]{2}$')
615        ReIsValidUint16z = re.compile('^0[x|X][a-fA-F0-9]{4}$')
616        ReIsValidUint32z = re.compile('^0[x|X][a-fA-F0-9]{8}$')
617        ReIsValidUint64z = re.compile('^0[x|X][a-fA-F0-9]{16}$')
618
619        if not ReIsValidUint8z.match(Value) and Type == 'UINT8':
620            return False
621        elif not ReIsValidUint16z.match(Value) and  Type == 'UINT16':
622            return False
623        elif not ReIsValidUint32z.match(Value) and  Type == 'UINT32':
624            return False
625        elif not ReIsValidUint64z.match(Value) and  Type == 'UINT64':
626            return False
627    else:
628        #
629        # Since we assume the DEC file always correct, should never go to here.
630        #
631        pass
632
633    return True
634
635def SetPcdName(PcdItem, CurrentLineOfPcdItem, PcdItemObj):
636    #
637    # Only PCD Name specified
638    # <PcdName> ::= <TokenSpaceGuidCName> "." <TokenCName>
639    #
640    PcdId = GetSplitValueList(PcdItem[0], DT.TAB_SPLIT)
641    if len(PcdId) != 2:
642        Logger.Error("InfParser",
643                     ToolError.FORMAT_INVALID,
644                     ST.ERR_INF_PARSER_PCD_NAME_FORMAT_ERROR,
645                     File=CurrentLineOfPcdItem[2],
646                     Line=CurrentLineOfPcdItem[1],
647                     ExtraData=CurrentLineOfPcdItem[0])
648    else:
649        #
650        # Validate PcdTokenSpaceGuidCName
651        #
652        if not IsValidCVariableName(PcdId[0]):
653            Logger.Error("InfParser",
654                         ToolError.FORMAT_INVALID,
655                         ST.ERR_INF_PARSER_PCD_CVAR_GUID,
656                         File=CurrentLineOfPcdItem[2],
657                         Line=CurrentLineOfPcdItem[1],
658                         ExtraData=PcdId[0])
659        if not IsValidCVariableName(PcdId[1]):
660            Logger.Error("InfParser",
661                         ToolError.FORMAT_INVALID,
662                         ST.ERR_INF_PARSER_PCD_CVAR_PCDCNAME,
663                         File=CurrentLineOfPcdItem[2],
664                         Line=CurrentLineOfPcdItem[1],
665                         ExtraData=PcdId[1])
666        PcdItemObj.SetTokenSpaceGuidCName(PcdId[0])
667        PcdItemObj.SetCName(PcdId[1])
668
669    return PcdItemObj
670