1## @file 2# This file contained the parser for [Pcds] sections in INF file 3# 4# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR> 5# 6# SPDX-License-Identifier: BSD-2-Clause-Patent 7# 8''' 9InfPcdSectionParser 10''' 11## 12# Import Modules 13# 14 15import Logger.Log as Logger 16from Logger import StringTable as ST 17from Logger.ToolError import FORMAT_INVALID 18from Parser.InfParserMisc import InfExpandMacro 19from Library import DataType as DT 20from Library.Parsing import MacroParser 21from Library.Misc import GetSplitValueList 22from Library import GlobalData 23from Library.StringUtils import SplitPcdEntry 24from Parser.InfParserMisc import InfParserSectionRoot 25 26class InfPcdSectionParser(InfParserSectionRoot): 27 ## Section PCD related parser 28 # 29 # For 5 types of PCD list below, all use this function. 30 # 'FixedPcd', 'FeaturePcd', 'PatchPcd', 'Pcd', 'PcdEx' 31 # 32 # This is a INF independent parser, the validation in this parser only 33 # cover 34 # INF spec scope, will not cross DEC/DSC to check pcd value 35 # 36 def InfPcdParser(self, SectionString, InfSectionObject, FileName): 37 KeysList = [] 38 PcdList = [] 39 CommentsList = [] 40 ValueList = [] 41 # 42 # Current section archs 43 # 44 LineIndex = -1 45 for Item in self.LastSectionHeaderContent: 46 if (Item[0], Item[1], Item[3]) not in KeysList: 47 KeysList.append((Item[0], Item[1], Item[3])) 48 LineIndex = Item[3] 49 50 if (Item[0].upper() == DT.TAB_INF_FIXED_PCD.upper() or \ 51 Item[0].upper() == DT.TAB_INF_FEATURE_PCD.upper() or \ 52 Item[0].upper() == DT.TAB_INF_PCD.upper()) and GlobalData.gIS_BINARY_INF: 53 Logger.Error('InfParser', FORMAT_INVALID, ST.ERR_ASBUILD_PCD_SECTION_TYPE%("\"" + Item[0] + "\""), 54 File=FileName, Line=LineIndex) 55 56 # 57 # For Common INF file 58 # 59 if not GlobalData.gIS_BINARY_INF: 60 # 61 # Macro defined in this section 62 # 63 SectionMacros = {} 64 for Line in SectionString: 65 PcdLineContent = Line[0] 66 PcdLineNo = Line[1] 67 if PcdLineContent.strip() == '': 68 CommentsList = [] 69 continue 70 71 if PcdLineContent.strip().startswith(DT.TAB_COMMENT_SPLIT): 72 CommentsList.append(Line) 73 continue 74 else: 75 # 76 # Encounter a PCD entry 77 # 78 if PcdLineContent.find(DT.TAB_COMMENT_SPLIT) > -1: 79 CommentsList.append(( 80 PcdLineContent[PcdLineContent.find(DT.TAB_COMMENT_SPLIT):], 81 PcdLineNo)) 82 PcdLineContent = PcdLineContent[:PcdLineContent.find(DT.TAB_COMMENT_SPLIT)] 83 84 if PcdLineContent != '': 85 # 86 # Find Macro 87 # 88 Name, Value = MacroParser((PcdLineContent, PcdLineNo), 89 FileName, 90 DT.MODEL_EFI_PCD, 91 self.FileLocalMacros) 92 if Name is not None: 93 SectionMacros[Name] = Value 94 ValueList = [] 95 CommentsList = [] 96 continue 97 98 PcdEntryReturn = SplitPcdEntry(PcdLineContent) 99 100 if not PcdEntryReturn[1]: 101 TokenList = [''] 102 else: 103 TokenList = PcdEntryReturn[0] 104 105 ValueList[0:len(TokenList)] = TokenList 106 107 # 108 # Replace with Local section Macro and [Defines] section Macro. 109 # 110 ValueList = [InfExpandMacro(Value, (FileName, PcdLineContent, PcdLineNo), 111 self.FileLocalMacros, SectionMacros, True) 112 for Value in ValueList] 113 114 if len(ValueList) >= 1: 115 PcdList.append((ValueList, CommentsList, (PcdLineContent, PcdLineNo, FileName))) 116 ValueList = [] 117 CommentsList = [] 118 continue 119 # 120 # For Binary INF file 121 # 122 else: 123 for Line in SectionString: 124 LineContent = Line[0].strip() 125 LineNo = Line[1] 126 127 if LineContent == '': 128 CommentsList = [] 129 continue 130 131 if LineContent.startswith(DT.TAB_COMMENT_SPLIT): 132 CommentsList.append(LineContent) 133 continue 134 # 135 # Have comments at tail. 136 # 137 CommentIndex = LineContent.find(DT.TAB_COMMENT_SPLIT) 138 if CommentIndex > -1: 139 CommentsList.append(LineContent[CommentIndex+1:]) 140 LineContent = LineContent[:CommentIndex] 141 142 TokenList = GetSplitValueList(LineContent, DT.TAB_VALUE_SPLIT) 143 # 144 # PatchablePcd 145 # TokenSpace.CName | Value | Offset 146 # 147 if KeysList[0][0].upper() == DT.TAB_INF_PATCH_PCD.upper(): 148 if len(TokenList) != 3: 149 Logger.Error('InfParser', 150 FORMAT_INVALID, 151 ST.ERR_ASBUILD_PATCHPCD_FORMAT_INVALID, 152 File=FileName, 153 Line=LineNo, 154 ExtraData=LineContent) 155 # 156 elif KeysList[0][0].upper() == DT.TAB_INF_PCD_EX.upper(): 157 if len(TokenList) != 1: 158 Logger.Error('InfParser', 159 FORMAT_INVALID, 160 ST.ERR_ASBUILD_PCDEX_FORMAT_INVALID, 161 File=FileName, 162 Line=LineNo, 163 ExtraData=LineContent) 164 ValueList[0:len(TokenList)] = TokenList 165 if len(ValueList) >= 1: 166 PcdList.append((ValueList, CommentsList, (LineContent, LineNo, FileName))) 167 ValueList = [] 168 CommentsList = [] 169 continue 170 171 if not InfSectionObject.SetPcds(PcdList, KeysList = KeysList, 172 PackageInfo = self.InfPackageSection.GetPackages()): 173 Logger.Error('InfParser', 174 FORMAT_INVALID, 175 ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR%("[PCD]"), 176 File=FileName, 177 Line=LineIndex) 178 179