#
            FindFlag = Line.find(u'//')
            if FindFlag != -1 and Line.find(u'//') < Line.find(u'"'):
                Line = Line.replace(Line[FindFlag:], u' ')
                if FileIn[LineCount].strip().startswith('#language'):
                    Line = Line + FileIn[LineCount]
                    FileIn[LineCount-1] = Line
                    FileIn[LineCount] = '\r\n'
                    LineCount -= 1
                    for Index in xrange (LineCount + 1, len (FileIn) - 1):
                        if (Index == len(FileIn) -1):
                            FileIn[Index] = '\r\n'
                        else:
                            FileIn[Index] = FileIn[Index + 1]
                    continue
            CommIndex = GetCharIndexOutStr(u'/', Line)
            if CommIndex > -1:
                if (len(Line) - 1) > CommIndex:
                    if Line[CommIndex+1] == u'/':
                        Line = Line[:CommIndex].strip()
                    else:
                        EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)
                else:
                    EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)
                    
            Line = Line.replace(UNICODE_WIDE_CHAR, WIDE_CHAR)
            Line = Line.replace(UNICODE_NARROW_CHAR, NARROW_CHAR)
            Line = Line.replace(UNICODE_NON_BREAKING_CHAR, NON_BREAKING_CHAR)

            Line = Line.replace(u'\\\\', u'\u0006')
            Line = Line.replace(u'\\r\\n', CR + LF)
Ejemplo n.º 2
0
    def PreProcess(self, File, IsIncludeFile=False):
        if not os.path.exists(File.Path) or not os.path.isfile(File.Path):
            EdkLogger.Error("Unicode File Parser",
                            ToolError.FILE_NOT_FOUND,
                            ExtraData=File.Path)

        #
        # Check file header of the Uni file
        #
        if not CheckUTF16FileHeader(File.Path):
            EdkLogger.Error(
                "Unicode File Parser",
                ToolError.FORMAT_INVALID,
                ExtraData=
                'The file %s is either invalid UTF-16LE or it is missing the BOM.'
                % File.Path)

        try:
            FileIn = codecs.open(File.Path, mode='rb',
                                 encoding='utf_16').readlines()
        except UnicodeError:
            FileIn = codecs.open(File.Path, mode='rb',
                                 encoding='utf_16_le').readlines()
        except:
            EdkLogger.Error("Unicode File Parser",
                            ToolError.FILE_OPEN_FAILURE,
                            ExtraData=File.Path)

        #
        # get the file header
        #
        Lines = []
        HeaderStart = False
        HeaderEnd = False
        if not self.UniFileHeader:
            FirstGenHeader = True
        else:
            FirstGenHeader = False
        for Line in FileIn:
            Line = Line.strip()
            if Line == u'':
                continue
            if Line.startswith(DT.TAB_COMMENT_EDK1_SPLIT) and (Line.find(DT.TAB_HEADER_COMMENT) > -1) \
                and not HeaderEnd and not HeaderStart:
                HeaderStart = True
            if not Line.startswith(DT.TAB_COMMENT_EDK1_SPLIT
                                   ) and HeaderStart and not HeaderEnd:
                HeaderEnd = True
            if Line.startswith(
                    DT.TAB_COMMENT_EDK1_SPLIT
            ) and HeaderStart and not HeaderEnd and FirstGenHeader:
                self.UniFileHeader += Line + '\r\n'
                continue

        #
        # Use unique identifier
        #
        FindFlag = -1
        LineCount = 0
        MultiLineFeedExits = False
        #
        # 0: initial value
        # 1: signle String entry exist
        # 2: line feed exist under the some signle String entry
        #
        StringEntryExistsFlag = 0
        for Line in FileIn:
            Line = FileIn[LineCount]
            LineCount += 1
            Line = Line.strip()
            #
            # Ignore comment line and empty line
            #
            if Line == u'' or Line.startswith(u'//'):
                #
                # Change the single line String entry flag status
                #
                if StringEntryExistsFlag == 1:
                    StringEntryExistsFlag = 2
                #
                # If the '#string' line and the '#language' line are not in the same line,
                # there should be only one line feed character betwwen them
                #
                if MultiLineFeedExits:
                    EdkLogger.Error("Unicode File Parser",
                                    ToolError.FORMAT_INVALID,
                                    ExtraData=File.Path)
                continue

            MultiLineFeedExits = False
            #
            # Process comment embeded in string define lines
            #
            FindFlag = Line.find(u'//')
            if FindFlag != -1 and Line.find(u'//') < Line.find(u'"'):
                Line = Line.replace(Line[FindFlag:], u' ')
                if FileIn[LineCount].strip().startswith('#language'):
                    Line = Line + FileIn[LineCount]
                    FileIn[LineCount - 1] = Line
                    FileIn[LineCount] = '\r\n'
                    LineCount -= 1
                    for Index in xrange(LineCount + 1, len(FileIn) - 1):
                        if (Index == len(FileIn) - 1):
                            FileIn[Index] = '\r\n'
                        else:
                            FileIn[Index] = FileIn[Index + 1]
                    continue
            CommIndex = GetCharIndexOutStr(u'/', Line)
            if CommIndex > -1:
                if (len(Line) - 1) > CommIndex:
                    if Line[CommIndex + 1] == u'/':
                        Line = Line[:CommIndex].strip()
                    else:
                        EdkLogger.Error("Unicode File Parser",
                                        ToolError.FORMAT_INVALID,
                                        ExtraData=File.Path)
                else:
                    EdkLogger.Error("Unicode File Parser",
                                    ToolError.FORMAT_INVALID,
                                    ExtraData=File.Path)

            Line = Line.replace(UNICODE_WIDE_CHAR, WIDE_CHAR)
            Line = Line.replace(UNICODE_NARROW_CHAR, NARROW_CHAR)
            Line = Line.replace(UNICODE_NON_BREAKING_CHAR, NON_BREAKING_CHAR)

            Line = Line.replace(u'\\\\', u'\u0006')
            Line = Line.replace(u'\\r\\n', CR + LF)
            Line = Line.replace(u'\\n', CR + LF)
            Line = Line.replace(u'\\r', CR)
            Line = Line.replace(u'\\t', u'\t')
            Line = Line.replace(u'''\"''', u'''"''')
            Line = Line.replace(u'\t', u' ')
            Line = Line.replace(u'\u0006', u'\\')

            # IncList = gINCLUDE_PATTERN.findall(Line)
            IncList = []
            if len(IncList) == 1:
                for Dir in [File.Dir] + self.IncludePathList:
                    IncFile = PathClass(str(IncList[0]), Dir)
                    self.IncFileList.append(IncFile)
                    if os.path.isfile(IncFile.Path):
                        Lines.extend(self.PreProcess(IncFile, True))
                        break
                else:
                    EdkLogger.Error("Unicode File Parser",
                                    ToolError.FILE_NOT_FOUND,
                                    Message="Cannot find include file",
                                    ExtraData=str(IncList[0]))
                continue

            #
            # Between Name entry and Language entry can not contain line feed
            #
            if Line.startswith(u'#string') and Line.find(u'#language') == -1:
                MultiLineFeedExits = True

            if Line.startswith(u'#string') and Line.find(
                    u'#language') > 0 and Line.find(u'"') < 0:
                MultiLineFeedExits = True

            #
            # Between Language entry and String entry can not contain line feed
            #
            if Line.startswith(u'#language') and len(Line.split()) == 2:
                MultiLineFeedExits = True

            #
            # Between two String entry, can not contain line feed
            #
            if Line.startswith(u'"'):
                if StringEntryExistsFlag == 2:
                    EdkLogger.Error("Unicode File Parser",
                                    ToolError.FORMAT_INVALID,
                                    Message=ST.ERR_UNIPARSE_LINEFEED_UP_EXIST %
                                    Line,
                                    ExtraData=File.Path)

                StringEntryExistsFlag = 1
                if not Line.endswith('"'):
                    EdkLogger.Error(
                        "Unicode File Parser",
                        ToolError.FORMAT_INVALID,
                        ExtraData=
                        '''The line %s misses '"' at the end of it in file %s'''
                        % (LineCount, File.Path))
            elif Line.startswith(u'#language'):
                if StringEntryExistsFlag == 2:
                    EdkLogger.Error("Unicode File Parser",
                                    ToolError.FORMAT_INVALID,
                                    Message=ST.ERR_UNI_MISS_STRING_ENTRY %
                                    Line,
                                    ExtraData=File.Path)
                StringEntryExistsFlag = 0
            else:
                StringEntryExistsFlag = 0

            Lines.append(Line)

        #
        # Convert string def format as below
        #
        #     #string MY_STRING_1
        #     #language eng
        #     "My first English string line 1"
        #     "My first English string line 2"
        #     #string MY_STRING_1
        #     #language spa
        #     "Mi segunda secuencia 1"
        #     "Mi segunda secuencia 2"
        #

        if not IsIncludeFile and not Lines:
            EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \
                Message=ST.ERR_UNIPARSE_NO_SECTION_EXIST, \
                ExtraData=File.Path)

        NewLines = []
        StrName = u''
        ExistStrNameList = []
        for Line in Lines:
            if StrName and not StrName.split()[1].startswith(
                    DT.TAB_STR_TOKENCNAME + DT.TAB_UNDERLINE_SPLIT):
                EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \
                                Message=ST.ERR_UNIPARSE_STRNAME_FORMAT_ERROR % StrName.split()[1], \
                                ExtraData=File.Path)

            if StrName and len(StrName.split()[1].split(
                    DT.TAB_UNDERLINE_SPLIT)) == 4:
                StringTokenList = StrName.split()[1].split(
                    DT.TAB_UNDERLINE_SPLIT)
                if (StringTokenList[3].upper() in [DT.TAB_STR_TOKENPROMPT, DT.TAB_STR_TOKENHELP] and \
                    StringTokenList[3] not in [DT.TAB_STR_TOKENPROMPT, DT.TAB_STR_TOKENHELP]) or \
                    (StringTokenList[2].upper() == DT.TAB_STR_TOKENERR and StringTokenList[2] != DT.TAB_STR_TOKENERR):
                    EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \
                                Message=ST.ERR_UNIPARSE_STRTOKEN_FORMAT_ERROR % StrName.split()[1], \
                                ExtraData=File.Path)

            if Line.count(u'#language') > 1:
                EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \
                                Message=ST.ERR_UNIPARSE_SEP_LANGENTRY_LINE % Line, \
                                ExtraData=File.Path)

            if Line.startswith(u'//'):
                continue
            elif Line.startswith(u'#langdef'):
                if len(Line.split()) == 2:
                    NewLines.append(Line)
                    continue
                elif len(Line.split()) > 2 and Line.find(u'"') > 0:
                    NewLines.append(Line[:Line.find(u'"')].strip())
                    NewLines.append(Line[Line.find(u'"'):])
                else:
                    EdkLogger.Error("Unicode File Parser",
                                    ToolError.FORMAT_INVALID,
                                    ExtraData=File.Path)
            elif Line.startswith(u'#string'):
                if len(Line.split()) == 2:
                    StrName = Line
                    if StrName:
                        if StrName.split()[1] not in ExistStrNameList:
                            ExistStrNameList.append(StrName.split()[1].strip())
                        elif StrName.split()[1] in [DT.TAB_INF_ABSTRACT, DT.TAB_INF_DESCRIPTION, \
                                                    DT.TAB_INF_BINARY_ABSTRACT, DT.TAB_INF_BINARY_DESCRIPTION, \
                                                    DT.TAB_DEC_PACKAGE_ABSTRACT, DT.TAB_DEC_PACKAGE_DESCRIPTION, \
                                                    DT.TAB_DEC_BINARY_ABSTRACT, DT.TAB_DEC_BINARY_DESCRIPTION]:
                            EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \
                                            Message=ST.ERR_UNIPARSE_MULTI_ENTRY_EXIST % StrName.split()[1], \
                                            ExtraData=File.Path)
                    continue
                elif len(Line.split()) == 4 and Line.find(u'#language') > 0:
                    if Line[Line.find(u'#language')-1] != ' ' or \
                       Line[Line.find(u'#language')+len(u'#language')] != u' ':
                        EdkLogger.Error("Unicode File Parser",
                                        ToolError.FORMAT_INVALID,
                                        ExtraData=File.Path)

                    if Line.find(u'"') > 0:
                        EdkLogger.Error("Unicode File Parser",
                                        ToolError.FORMAT_INVALID,
                                        ExtraData=File.Path)

                    StrName = Line.split()[0] + u' ' + Line.split()[1]
                    if StrName:
                        if StrName.split()[1] not in ExistStrNameList:
                            ExistStrNameList.append(StrName.split()[1].strip())
                        elif StrName.split()[1] in [DT.TAB_INF_ABSTRACT, DT.TAB_INF_DESCRIPTION, \
                                                    DT.TAB_INF_BINARY_ABSTRACT, DT.TAB_INF_BINARY_DESCRIPTION, \
                                                    DT.TAB_DEC_PACKAGE_ABSTRACT, DT.TAB_DEC_PACKAGE_DESCRIPTION, \
                                                    DT.TAB_DEC_BINARY_ABSTRACT, DT.TAB_DEC_BINARY_DESCRIPTION]:
                            EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \
                                            Message=ST.ERR_UNIPARSE_MULTI_ENTRY_EXIST % StrName.split()[1], \
                                            ExtraData=File.Path)
                    if IsIncludeFile:
                        if StrName not in NewLines:
                            NewLines.append(
                                (Line[:Line.find(u'#language')]).strip())
                    else:
                        NewLines.append(
                            (Line[:Line.find(u'#language')]).strip())
                    NewLines.append((Line[Line.find(u'#language'):]).strip())
                elif len(Line.split()) > 4 and Line.find(
                        u'#language') > 0 and Line.find(u'"') > 0:
                    if Line[Line.find(u'#language')-1] != u' ' or \
                       Line[Line.find(u'#language')+len(u'#language')] != u' ':
                        EdkLogger.Error("Unicode File Parser",
                                        ToolError.FORMAT_INVALID,
                                        ExtraData=File.Path)

                    if Line[Line.find(u'"') - 1] != u' ':
                        EdkLogger.Error("Unicode File Parser",
                                        ToolError.FORMAT_INVALID,
                                        ExtraData=File.Path)

                    StrName = Line.split()[0] + u' ' + Line.split()[1]
                    if StrName:
                        if StrName.split()[1] not in ExistStrNameList:
                            ExistStrNameList.append(StrName.split()[1].strip())
                        elif StrName.split()[1] in [DT.TAB_INF_ABSTRACT, DT.TAB_INF_DESCRIPTION, \
                                                    DT.TAB_INF_BINARY_ABSTRACT, DT.TAB_INF_BINARY_DESCRIPTION, \
                                                    DT.TAB_DEC_PACKAGE_ABSTRACT, DT.TAB_DEC_PACKAGE_DESCRIPTION, \
                                                    DT.TAB_DEC_BINARY_ABSTRACT, DT.TAB_DEC_BINARY_DESCRIPTION]:
                            EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \
                                            Message=ST.ERR_UNIPARSE_MULTI_ENTRY_EXIST % StrName.split()[1], \
                                            ExtraData=File.Path)
                    if IsIncludeFile:
                        if StrName not in NewLines:
                            NewLines.append(
                                (Line[:Line.find(u'#language')]).strip())
                    else:
                        NewLines.append(
                            (Line[:Line.find(u'#language')]).strip())
                    NewLines.append((
                        Line[Line.find(u'#language'):Line.find(u'"')]).strip())
                    NewLines.append((Line[Line.find(u'"'):]).strip())
                else:
                    EdkLogger.Error("Unicode File Parser",
                                    ToolError.FORMAT_INVALID,
                                    ExtraData=File.Path)
            elif Line.startswith(u'#language'):
                if len(Line.split()) == 2:
                    if IsIncludeFile:
                        if StrName not in NewLines:
                            NewLines.append(StrName)
                    else:
                        NewLines.append(StrName)
                    NewLines.append(Line)
                elif len(Line.split()) > 2 and Line.find(u'"') > 0:
                    if IsIncludeFile:
                        if StrName not in NewLines:
                            NewLines.append(StrName)
                    else:
                        NewLines.append(StrName)
                    NewLines.append((Line[:Line.find(u'"')]).strip())
                    NewLines.append((Line[Line.find(u'"'):]).strip())
                else:
                    EdkLogger.Error("Unicode File Parser",
                                    ToolError.FORMAT_INVALID,
                                    ExtraData=File.Path)
            elif Line.startswith(u'"'):
                if u'#string' in Line or u'#language' in Line:
                    EdkLogger.Error("Unicode File Parser",
                                    ToolError.FORMAT_INVALID,
                                    ExtraData=File.Path)
                NewLines.append(Line)
            else:
                print Line
                EdkLogger.Error("Unicode File Parser",
                                ToolError.FORMAT_INVALID,
                                ExtraData=File.Path)

        if StrName and not StrName.split()[1].startswith(u'STR_'):
            EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \
                                Message=ST.ERR_UNIPARSE_STRNAME_FORMAT_ERROR % StrName.split()[1], \
                                ExtraData=File.Path)

        if StrName and not NewLines:
            EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \
                            Message=ST.ERR_UNI_MISS_LANGENTRY % StrName, \
                            ExtraData=File.Path)

        #
        # Check Abstract, Description, BinaryAbstract and BinaryDescription order,
        # should be Abstract, Description, BinaryAbstract, BinaryDesctiption
        AbstractPosition = -1
        DescriptionPosition = -1
        BinaryAbstractPosition = -1
        BinaryDescriptionPosition = -1
        for StrName in ExistStrNameList:
            if DT.TAB_HEADER_ABSTRACT.upper() in StrName:
                if 'BINARY' in StrName:
                    BinaryAbstractPosition = ExistStrNameList.index(StrName)
                else:
                    AbstractPosition = ExistStrNameList.index(StrName)
            if DT.TAB_HEADER_DESCRIPTION.upper() in StrName:
                if 'BINARY' in StrName:
                    BinaryDescriptionPosition = ExistStrNameList.index(StrName)
                else:
                    DescriptionPosition = ExistStrNameList.index(StrName)

        OrderList = sorted([AbstractPosition, DescriptionPosition])
        BinaryOrderList = sorted(
            [BinaryAbstractPosition, BinaryDescriptionPosition])
        Min = OrderList[0]
        Max = OrderList[1]
        BinaryMin = BinaryOrderList[0]
        BinaryMax = BinaryOrderList[1]
        if BinaryDescriptionPosition > -1:
            if not(BinaryDescriptionPosition == BinaryMax and BinaryAbstractPosition == BinaryMin and \
                   BinaryMax > Max):
                EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \
                                Message=ST.ERR_UNIPARSE_ENTRY_ORDER_WRONG, \
                                ExtraData=File.Path)
        elif BinaryAbstractPosition > -1:
            if not (BinaryAbstractPosition > Max):
                EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \
                                Message=ST.ERR_UNIPARSE_ENTRY_ORDER_WRONG, \
                                ExtraData=File.Path)

        if DescriptionPosition > -1:
            if not(DescriptionPosition == Max and AbstractPosition == Min and \
                   DescriptionPosition > AbstractPosition):
                EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \
                                Message=ST.ERR_UNIPARSE_ENTRY_ORDER_WRONG, \
                                ExtraData=File.Path)

        if not self.UniFileHeader:
            EdkLogger.Error("Unicode File Parser",
                            ToolError.FORMAT_INVALID,
                            Message=ST.ERR_NO_SOURCE_HEADER,
                            ExtraData=File.Path)

        return NewLines