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