Exemple #1
0
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, 'r').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)
Exemple #2
0
    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)
Exemple #3
0
    def __init__(self, DecFile, Parse = True):
        try:
            Content = ConvertSpecialChar(open(DecFile, 'r').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()