def __init__(self, DecFile, Parse=True): try: Content = ConvertSpecialChar(open(DecFile, 'rb').readlines()) except BaseException: Logger.Error(TOOL_NAME, FILE_OPEN_FAILURE, File=DecFile, ExtraData=ST.ERR_DECPARSE_FILEOPEN % DecFile) RawData = FileContent(DecFile, Content) _DecComments.__init__(self) _DecBase.__init__(self, RawData) self.BinaryHeadComment = [] self.PcdErrorCommentDict = {} self._Define = _DecDefine(RawData) self._Include = _DecInclude(RawData) self._Guid = _DecGuid(RawData) self._LibClass = _DecLibraryclass(RawData) self._Pcd = _DecPcd(RawData) self._UserEx = _DecUserExtension(RawData) # # DEC file supported data types (one type per section) # self._SectionParser = { DT.TAB_DEC_DEFINES.upper(): self._Define, DT.TAB_INCLUDES.upper(): self._Include, DT.TAB_LIBRARY_CLASSES.upper(): self._LibClass, DT.TAB_GUIDS.upper(): self._Guid, DT.TAB_PPIS.upper(): self._Guid, DT.TAB_PROTOCOLS.upper(): self._Guid, DT.TAB_PCDS_FIXED_AT_BUILD_NULL.upper(): self._Pcd, DT.TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper(): self._Pcd, DT.TAB_PCDS_FEATURE_FLAG_NULL.upper(): self._Pcd, DT.TAB_PCDS_DYNAMIC_NULL.upper(): self._Pcd, DT.TAB_PCDS_DYNAMIC_EX_NULL.upper(): self._Pcd, DT.TAB_USER_EXTENSIONS.upper(): self._UserEx } if Parse: self.ParseDecComment() self.Parse() # # Parsing done, check required fields # self.CheckRequiredFields()
def ParseInfFile(self, Filename): Filename = NormPath(Filename) (Path, Name) = os.path.split(Filename) self.FullPath = Filename self.RelaPath = Path self.FileName = Name GlobalData.gINF_MODULE_DIR = Path GlobalData.gINF_MODULE_NAME = self.FullPath GlobalData.gIS_BINARY_INF = False # # Initialize common data # LineNo = 0 CurrentSection = DT.MODEL_UNKNOWN SectionLines = [] # # Flags # HeaderCommentStart = False HeaderCommentEnd = False HeaderStarLineNo = -1 BinaryHeaderCommentStart = False BinaryHeaderCommentEnd = False BinaryHeaderStarLineNo = -1 # # While Section ends. parse whole section contents. # NewSectionStartFlag = False FirstSectionStartFlag = False # # Parse file content # CommentBlock = [] # # Variables for Event/Hob/BootMode # self.EventList = [] self.HobList = [] self.BootModeList = [] SectionType = '' FileLinesList = OpenInfFile(Filename) # # One INF file can only has one [Defines] section. # DefineSectionParsedFlag = False # # Convert special characters in lines to space character. # FileLinesList = ConvertSpecialChar(FileLinesList) # # Process Line Extender # FileLinesList = ProcessLineExtender(FileLinesList) # # Process EdkI INF style comment if found # OrigLines = [Line for Line in FileLinesList] FileLinesList, EdkCommentStartPos = ProcessEdkComment(FileLinesList) # # Judge whether the INF file is Binary INF or not # if IsBinaryInf(FileLinesList): GlobalData.gIS_BINARY_INF = True InfSectionCommonDefObj = None for Line in FileLinesList: LineNo = LineNo + 1 Line = Line.strip() if (LineNo < len(FileLinesList) - 1): NextLine = FileLinesList[LineNo].strip() # # blank line # if (Line == '' or not Line) and LineNo == len(FileLinesList): LastSectionFalg = True # # check whether file header comment section started # if Line.startswith(DT.TAB_SPECIAL_COMMENT) and \ (Line.find(DT.TAB_HEADER_COMMENT) > -1) and \ not HeaderCommentStart and not HeaderCommentEnd: CurrentSection = DT.MODEL_META_DATA_FILE_HEADER # # Append the first line to section lines. # HeaderStarLineNo = LineNo SectionLines.append((Line, LineNo)) HeaderCommentStart = True continue # # Collect Header content. # if (Line.startswith(DT.TAB_COMMENT_SPLIT) and CurrentSection == DT.MODEL_META_DATA_FILE_HEADER) and\ HeaderCommentStart and not Line.startswith(DT.TAB_SPECIAL_COMMENT) and not\ HeaderCommentEnd and NextLine != '': SectionLines.append((Line, LineNo)) continue # # Header content end # if (Line.startswith(DT.TAB_SPECIAL_COMMENT) or not Line.strip().startswith("#")) and HeaderCommentStart \ and not HeaderCommentEnd: HeaderCommentEnd = True BinaryHeaderCommentStart = False BinaryHeaderCommentEnd = False HeaderCommentStart = False if Line.find(DT.TAB_BINARY_HEADER_COMMENT) > -1: self.InfHeaderParser(SectionLines, self.InfHeader, self.FileName) SectionLines = [] else: SectionLines.append((Line, LineNo)) # # Call Header comment parser. # self.InfHeaderParser(SectionLines, self.InfHeader, self.FileName) SectionLines = [] continue # # check whether binary header comment section started # if Line.startswith(DT.TAB_SPECIAL_COMMENT) and \ (Line.find(DT.TAB_BINARY_HEADER_COMMENT) > -1) and \ not BinaryHeaderCommentStart: SectionLines = [] CurrentSection = DT.MODEL_META_DATA_FILE_HEADER # # Append the first line to section lines. # BinaryHeaderStarLineNo = LineNo SectionLines.append((Line, LineNo)) BinaryHeaderCommentStart = True HeaderCommentEnd = True continue # # check whether there are more than one binary header exist # if Line.startswith(DT.TAB_SPECIAL_COMMENT) and BinaryHeaderCommentStart and \ not BinaryHeaderCommentEnd and (Line.find(DT.TAB_BINARY_HEADER_COMMENT) > -1): Logger.Error('Parser', FORMAT_INVALID, ST.ERR_MULTIPLE_BINARYHEADER_EXIST, File=Filename) # # Collect Binary Header content. # if (Line.startswith(DT.TAB_COMMENT_SPLIT) and CurrentSection == DT.MODEL_META_DATA_FILE_HEADER) and\ BinaryHeaderCommentStart and not Line.startswith(DT.TAB_SPECIAL_COMMENT) and not\ BinaryHeaderCommentEnd and NextLine != '': SectionLines.append((Line, LineNo)) continue # # Binary Header content end # if (Line.startswith(DT.TAB_SPECIAL_COMMENT) or not Line.strip().startswith(DT.TAB_COMMENT_SPLIT)) and \ BinaryHeaderCommentStart and not BinaryHeaderCommentEnd: SectionLines.append((Line, LineNo)) BinaryHeaderCommentStart = False # # Call Binary Header comment parser. # self.InfHeaderParser(SectionLines, self.InfBinaryHeader, self.FileName, True) SectionLines = [] BinaryHeaderCommentEnd = True continue # # Find a new section tab # Or at the last line of INF file, # need to process the last section. # LastSectionFalg = False if LineNo == len(FileLinesList): LastSectionFalg = True if Line.startswith(DT.TAB_COMMENT_SPLIT) and not Line.startswith( DT.TAB_SPECIAL_COMMENT): SectionLines.append((Line, LineNo)) if not LastSectionFalg: continue # # Encountered a section. start with '[' and end with ']' # if (Line.startswith(DT.TAB_SECTION_START) and \ Line.find(DT.TAB_SECTION_END) > -1) or LastSectionFalg: HeaderCommentEnd = True BinaryHeaderCommentEnd = True if not LastSectionFalg: # # check to prevent '#' inside section header # HeaderContent = Line[1:Line.find(DT.TAB_SECTION_END)] if HeaderContent.find(DT.TAB_COMMENT_SPLIT) != -1: Logger.Error( "InfParser", FORMAT_INVALID, ST.ERR_INF_PARSER_DEFINE_SECTION_HEADER_INVALID, File=self.FullPath, Line=LineNo, ExtraData=Line) # # Keep last time section header content for section parser # usage. # self.LastSectionHeaderContent = deepcopy( self.SectionHeaderContent) # # TailComments in section define. # TailComments = '' CommentIndex = Line.find(DT.TAB_COMMENT_SPLIT) if CommentIndex > -1: TailComments = Line[CommentIndex:] Line = Line[:CommentIndex] InfSectionCommonDefObj = InfSectionCommonDef() if TailComments != '': InfSectionCommonDefObj.SetTailComments(TailComments) if CommentBlock != '': InfSectionCommonDefObj.SetHeaderComments(CommentBlock) CommentBlock = [] # # Call section parser before section header parer to avoid encounter EDKI INF file # if CurrentSection == DT.MODEL_META_DATA_DEFINE: DefineSectionParsedFlag = self._CallSectionParsers( CurrentSection, DefineSectionParsedFlag, SectionLines, InfSectionCommonDefObj, LineNo) # # Compare the new section name with current # self.SectionHeaderParser(Line, self.FileName, LineNo) self._CheckSectionHeaders(Line, LineNo) SectionType = _ConvertSecNameToType( self.SectionHeaderContent[0][0]) if not FirstSectionStartFlag: CurrentSection = SectionType FirstSectionStartFlag = True else: NewSectionStartFlag = True else: SectionLines.append((Line, LineNo)) continue if LastSectionFalg: SectionLines, CurrentSection = self._ProcessLastSection( SectionLines, Line, LineNo, CurrentSection) # # End of section content collect. # Parser the section content collected previously. # if NewSectionStartFlag or LastSectionFalg: if CurrentSection != DT.MODEL_META_DATA_DEFINE or \ (LastSectionFalg and CurrentSection == DT.MODEL_META_DATA_DEFINE): DefineSectionParsedFlag = self._CallSectionParsers( CurrentSection, DefineSectionParsedFlag, SectionLines, InfSectionCommonDefObj, LineNo) CurrentSection = SectionType # # Clear section lines # SectionLines = [] if HeaderStarLineNo == -1: Logger.Error("InfParser", FORMAT_INVALID, ST.ERR_NO_SOURCE_HEADER, File=self.FullPath) if BinaryHeaderStarLineNo > -1 and HeaderStarLineNo > -1 and HeaderStarLineNo > BinaryHeaderStarLineNo: Logger.Error("InfParser", FORMAT_INVALID, ST.ERR_BINARY_HEADER_ORDER, File=self.FullPath) # # EDKII INF should not have EDKI style comment # if EdkCommentStartPos != -1: Logger.Error("InfParser", FORMAT_INVALID, ST.ERR_INF_PARSER_EDKI_COMMENT_IN_EDKII, File=self.FullPath, Line=EdkCommentStartPos + 1, ExtraData=OrigLines[EdkCommentStartPos]) # # extract [Event] [Hob] [BootMode] sections # self._ExtractEventHobBootMod(FileLinesList)
def IniToXml(IniFile): if not os.path.exists(IniFile): Logger.Error("UPT", FILE_NOT_FOUND, ST.ERR_TEMPLATE_NOTFOUND % IniFile) DistMap = { 'ReadOnly': '', 'RePackage': '', 'Name': '', 'BaseName': '', 'GUID': '', 'Version': '', 'Vendor': '', 'Date': '', 'Copyright': '', 'License': '', 'Abstract': '', 'Description': '', 'Signature': '', 'XmlSpecification': '' } ToolsMap = { 'Name': '', 'Copyright': '', 'License': '', 'Abstract': '', 'Description': '', 'FileList': [] } # # Only FileList is a list: [['file1', {}], ['file2', {}], ...] # MiscMap = { 'Name': '', 'Copyright': '', 'License': '', 'Abstract': '', 'Description': '', 'FileList': [] } SectionMap = { 'DistributionHeader': DistMap, 'ToolsHeader': ToolsMap, 'MiscellaneousFilesHeader': MiscMap } PathValidator = { 'ToolsHeader': ValidateToolsFile, 'MiscellaneousFilesHeader': ValidateMiscFile } ParsedSection = [] SectionName = '' CurrentKey = '' PreMap = None Map = None FileContent = ConvertSpecialChar(open(IniFile, 'rb').readlines()) LastIndex = 0 for Index in range(0, len(FileContent)): LastIndex = Index Line = FileContent[Index].strip() if Line == '' or Line.startswith(';'): continue if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END: CurrentKey = '' SectionName = Line[1:-1].strip() if SectionName not in SectionMap: IniParseError(ST.ERR_SECTION_NAME_INVALID % SectionName, IniFile, Index + 1) if SectionName in ParsedSection: IniParseError(ST.ERR_SECTION_REDEFINE % SectionName, IniFile, Index + 1) else: ParsedSection.append(SectionName) Map = SectionMap[SectionName] continue if not Map: IniParseError(ST.ERR_SECTION_NAME_NONE, IniFile, Index + 1) TokenList = Line.split(TAB_EQUAL_SPLIT, 1) TempKey = TokenList[0].strip() # # Value spanned multiple or same keyword appears more than one time # if len(TokenList) < 2 or TempKey not in Map: if CurrentKey == '': IniParseError(ST.ERR_KEYWORD_INVALID % TempKey, IniFile, Index + 1) elif CurrentKey == 'FileList': # # Special for FileList # Valid, Cause = ParseFileList(Line, Map, CurrentKey, PathValidator[SectionName]) if not Valid: IniParseError(Cause, IniFile, Index + 1) else: # # Multiple lines for one key such as license # Or if string on the left side of '=' is not a keyword # Map[CurrentKey] = ''.join([Map[CurrentKey], '\n', Line]) Valid, Cause = ValidateValues(CurrentKey, Map[CurrentKey], SectionName) if not Valid: IniParseError(Cause, IniFile, Index + 1) continue if (TokenList[1].strip() == ''): IniParseError(ST.ERR_EMPTY_VALUE, IniFile, Index + 1) # # A keyword found # CurrentKey = TempKey if Map[CurrentKey]: IniParseError(ST.ERR_KEYWORD_REDEFINE % CurrentKey, IniFile, Index + 1) if id(Map) != id(PreMap) and Map['Copyright']: PreMap = Map Copyright = Map['Copyright'].lower() Pos = Copyright.find('copyright') if Pos == -1: IniParseError(ST.ERR_COPYRIGHT_CONTENT, IniFile, Index) if not Copyright[Pos + len('copyright'):].lstrip(' ').startswith('('): IniParseError(ST.ERR_COPYRIGHT_CONTENT, IniFile, Index) if CurrentKey == 'FileList': Valid, Cause = ParseFileList(TokenList[1], Map, CurrentKey, PathValidator[SectionName]) if not Valid: IniParseError(Cause, IniFile, Index + 1) else: Map[CurrentKey] = TokenList[1].strip() Valid, Cause = ValidateValues(CurrentKey, Map[CurrentKey], SectionName) if not Valid: IniParseError(Cause, IniFile, Index + 1) if id(Map) != id(PreMap) and Map['Copyright'] and 'copyright' not in Map[ 'Copyright'].lower(): IniParseError(ST.ERR_COPYRIGHT_CONTENT, IniFile, LastIndex) # # Check mandatory keys # CheckMdtKeys(DistMap, IniFile, LastIndex, (('ToolsHeader', ToolsMap), ('MiscellaneousFilesHeader', MiscMap))) return CreateXml(DistMap, ToolsMap, MiscMap, IniFile)
def __init__(self, DecFile, Parse = True): try: Content = ConvertSpecialChar(open(DecFile, 'rb').readlines()) except BaseException: Logger.Error(TOOL_NAME, FILE_OPEN_FAILURE, File=DecFile, ExtraData=ST.ERR_DECPARSE_FILEOPEN % DecFile) # # Pre-parser for Private section # self._Private = '' __IsFoundPrivate = False NewContent = [] for Line in Content: Line = Line.strip() if Line.startswith(DT.TAB_SECTION_START) and Line.endswith(DT.TAB_PRIVATE + DT.TAB_SECTION_END): __IsFoundPrivate = True if Line.startswith(DT.TAB_SECTION_START) and Line.endswith(DT.TAB_SECTION_END)\ and not Line.endswith(DT.TAB_PRIVATE + DT.TAB_SECTION_END): __IsFoundPrivate = False if __IsFoundPrivate: self._Private += Line + '\r' if not __IsFoundPrivate: NewContent.append(Line + '\r') RawData = FileContent(DecFile, NewContent) _DecComments.__init__(self) _DecBase.__init__(self, RawData) self.BinaryHeadComment = [] self.PcdErrorCommentDict = {} self._Define = _DecDefine(RawData) self._Include = _DecInclude(RawData) self._Guid = _DecGuid(RawData) self._LibClass = _DecLibraryclass(RawData) self._Pcd = _DecPcd(RawData) self._UserEx = _DecUserExtension(RawData) # # DEC file supported data types (one type per section) # self._SectionParser = { DT.TAB_DEC_DEFINES.upper() : self._Define, DT.TAB_INCLUDES.upper() : self._Include, DT.TAB_LIBRARY_CLASSES.upper() : self._LibClass, DT.TAB_GUIDS.upper() : self._Guid, DT.TAB_PPIS.upper() : self._Guid, DT.TAB_PROTOCOLS.upper() : self._Guid, DT.TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : self._Pcd, DT.TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : self._Pcd, DT.TAB_PCDS_FEATURE_FLAG_NULL.upper() : self._Pcd, DT.TAB_PCDS_DYNAMIC_NULL.upper() : self._Pcd, DT.TAB_PCDS_DYNAMIC_EX_NULL.upper() : self._Pcd, DT.TAB_USER_EXTENSIONS.upper() : self._UserEx } if Parse: self.ParseDecComment() self.Parse() # # Parsing done, check required fields # self.CheckRequiredFields()