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