X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FAutoGen%2FStrGather.py;h=73af1214eb0acf7e6a5938d226a3c07a3de94dd3;hb=ff5635e9acbf8a4d0c4095e78f72f97ae94ce43b;hp=52ab439e9b0b5129d5a827fabb93532f8017834d;hpb=756ad8f8e9d3e345f1883546e2a3125203e234aa;p=mirror_edk2.git diff --git a/BaseTools/Source/Python/AutoGen/StrGather.py b/BaseTools/Source/Python/AutoGen/StrGather.py index 52ab439e9b..73af1214eb 100644 --- a/BaseTools/Source/Python/AutoGen/StrGather.py +++ b/BaseTools/Source/Python/AutoGen/StrGather.py @@ -1,4 +1,8 @@ -# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
+## @file +# This file is used to parse a strings file and create or add to a string database +# file. +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
# This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License # which accompanies this distribution. The full text of the license may be found at @@ -7,10 +11,6 @@ # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -#This file is used to parse a strings file and create or add to a string database file. -# - ## # Import Modules # @@ -19,7 +19,8 @@ import Common.EdkLogger as EdkLogger from Common.BuildToolError import * from UniClassObject import * from StringIO import StringIO -from struct import pack +from struct import pack, unpack +from Common.LongFilePathSupport import OpenLongFilePath as open ## # Static definitions @@ -58,11 +59,7 @@ NOT_REFERENCED = 'not referenced' COMMENT_NOT_REFERENCED = ' ' + COMMENT + NOT_REFERENCED CHAR_ARRAY_DEFIN = 'unsigned char' COMMON_FILE_NAME = 'Strings' -OFFSET = 'offset' -STRING = 'string' -TO = 'to' STRING_TOKEN = re.compile('STRING_TOKEN *\(([A-Z0-9_]+) *\)', re.MULTILINE | re.UNICODE) -COMPATIBLE_STRING_TOKEN = re.compile('STRING_TOKEN *\(([A-Za-z0-9_]+) *\)', re.MULTILINE | re.UNICODE) EFI_HII_ARRAY_SIZE_LENGTH = 4 EFI_HII_PACKAGE_HEADER_LENGTH = 4 @@ -97,7 +94,7 @@ PRINTABLE_LANGUAGE_NAME_STRING_NAME = '$PRINTABLE_LANGUAGE_NAME' # @retval: The formatted hex string # def DecToHexStr(Dec, Digit = 8): - return eval("'0x%0" + str(Digit) + "X' % int(Dec)") + return '0x{0:0{1}X}'.format(Dec,Digit) ## Convert a dec number to a hex list # @@ -112,11 +109,8 @@ def DecToHexStr(Dec, Digit = 8): # @retval: A list for formatted hex string # def DecToHexList(Dec, Digit = 8): - Hex = eval("'%0" + str(Digit) + "X' % int(Dec)" ) - List = [] - for Bit in range(Digit - 2, -1, -2): - List.append(HexHeader + Hex[Bit:Bit + 2]) - return List + Hex = '{0:0{1}X}'.format(Dec,Digit) + return ["0x" + Hex[Bit:Bit + 2] for Bit in range(Digit - 2, -1, -2)] ## Convert a acsii string to a hex list # @@ -128,27 +122,7 @@ def DecToHexList(Dec, Digit = 8): # @retval: A list for formatted hex string # def AscToHexList(Ascii): - List = [] - for Item in Ascii: - List.append('0x%2X' % ord(Item)) - - return List - -## Create header of .h file -# -# Create a header of .h file -# -# @param BaseName: The basename of strings -# -# @retval Str: A string for .h file header -# -def CreateHFileHeader(BaseName): - Str = '' - for Item in H_C_FILE_HEADER: - Str = WriteLine(Str, Item) - Str = WriteLine(Str, '#ifndef _' + BaseName.upper() + '_STRINGS_DEFINE_H_') - Str = WriteLine(Str, '#define _' + BaseName.upper() + '_STRINGS_DEFINE_H_') - return Str + return ['0x{0:02X}'.format(ord(Item)) for Item in Ascii] ## Create content of .h file # @@ -168,14 +142,15 @@ def CreateHFileContent(BaseName, UniObjectClass, IsCompatibleMode, UniGenCFlag): Str = WriteLine(Str, Line) Line = COMMENT_DEFINE_STR + ' ' + PRINTABLE_LANGUAGE_NAME_STRING_NAME + ' ' * (ValueStartPtr - len(DEFINE_STR + PRINTABLE_LANGUAGE_NAME_STRING_NAME)) + DecToHexStr(1, 4) + COMMENT_NOT_REFERENCED Str = WriteLine(Str, Line) + UnusedStr = '' - #Group the referred STRING token together. + #Group the referred/Unused STRING token together. for Index in range(2, len(UniObjectClass.OrderedStringList[UniObjectClass.LanguageDef[0][0]])): StringItem = UniObjectClass.OrderedStringList[UniObjectClass.LanguageDef[0][0]][Index] Name = StringItem.StringName Token = StringItem.Token Referenced = StringItem.Referenced - if Name != None: + if Name is not None: Line = '' if Referenced == True: if (ValueStartPtr - len(DEFINE_STR + Name)) <= 0: @@ -183,21 +158,14 @@ def CreateHFileContent(BaseName, UniObjectClass, IsCompatibleMode, UniGenCFlag): else: Line = DEFINE_STR + ' ' + Name + ' ' * (ValueStartPtr - len(DEFINE_STR + Name)) + DecToHexStr(Token, 4) Str = WriteLine(Str, Line) - - #Group the unused STRING token together. - for Index in range(2, len(UniObjectClass.OrderedStringList[UniObjectClass.LanguageDef[0][0]])): - StringItem = UniObjectClass.OrderedStringList[UniObjectClass.LanguageDef[0][0]][Index] - Name = StringItem.StringName - Token = StringItem.Token - Referenced = StringItem.Referenced - if Name != None: - Line = '' - if Referenced == False: + else: if (ValueStartPtr - len(DEFINE_STR + Name)) <= 0: Line = COMMENT_DEFINE_STR + ' ' + Name + ' ' + DecToHexStr(Token, 4) + COMMENT_NOT_REFERENCED else: Line = COMMENT_DEFINE_STR + ' ' + Name + ' ' * (ValueStartPtr - len(DEFINE_STR + Name)) + DecToHexStr(Token, 4) + COMMENT_NOT_REFERENCED - Str = WriteLine(Str, Line) + UnusedStr = WriteLine(UnusedStr, Line) + + Str = ''.join([Str, UnusedStr]) Str = WriteLine(Str, '') if IsCompatibleMode or UniGenCFlag: @@ -220,19 +188,6 @@ def CreateHFile(BaseName, UniObjectClass, IsCompatibleMode, UniGenCFlag): return HFile -## Create header of .c file -# -# Create a header of .c file -# -# @retval Str: A string for .c file header -# -def CreateCFileHeader(): - Str = '' - for Item in H_C_FILE_HEADER: - Str = WriteLine(Str, Item) - - return Str - ## Create a buffer to store all items in an array # # @param BinBuffer Buffer to contain Binary data. @@ -240,7 +195,7 @@ def CreateCFileHeader(): # def CreateBinBuffer(BinBuffer, Array): for Item in Array: - BinBuffer.write(pack("B", int(Item,16))) + BinBuffer.write(pack("B", int(Item, 16))) ## Create a formatted string all items in an array # @@ -263,7 +218,7 @@ def CreateArrayItem(Array, Width = 16): Index = Index + 1 else: ArrayItem = WriteLine(ArrayItem, Line) - Line = ' ' + Item + ', ' + Line = ' ' + Item + ', ' Index = 1 ArrayItem = Write(ArrayItem, Line.rstrip()) @@ -284,6 +239,65 @@ def CreateCFileStringValue(Value): return Str +## GetFilteredLanguage +# +# apply get best language rules to the UNI language code list +# +# @param UniLanguageList: language code definition list in *.UNI file +# @param LanguageFilterList: language code filter list of RFC4646 format in DSC file +# +# @retval UniLanguageListFiltered: the filtered language code +# +def GetFilteredLanguage(UniLanguageList, LanguageFilterList): + UniLanguageListFiltered = [] + # if filter list is empty, then consider there is no filter + if LanguageFilterList == []: + UniLanguageListFiltered = UniLanguageList + return UniLanguageListFiltered + for Language in LanguageFilterList: + # first check for exact match + if Language in UniLanguageList: + if Language not in UniLanguageListFiltered: + UniLanguageListFiltered += [Language] + # find the first one with the same/equivalent primary tag + else: + if Language.find('-') != -1: + PrimaryTag = Language[0:Language.find('-')].lower() + else: + PrimaryTag = Language + + if len(PrimaryTag) == 3: + PrimaryTag = LangConvTable.get(PrimaryTag) + + for UniLanguage in UniLanguageList: + if UniLanguage.find('-') != -1: + UniLanguagePrimaryTag = UniLanguage[0:UniLanguage.find('-')].lower() + else: + UniLanguagePrimaryTag = UniLanguage + + if len(UniLanguagePrimaryTag) == 3: + UniLanguagePrimaryTag = LangConvTable.get(UniLanguagePrimaryTag) + + if PrimaryTag == UniLanguagePrimaryTag: + if UniLanguage not in UniLanguageListFiltered: + UniLanguageListFiltered += [UniLanguage] + break + else: + # Here is rule 3 for "get best language" + # If tag is not listed in the Unicode file, the default ("en") tag should be used for that language + # for better processing, find the one that best suit for it. + DefaultTag = 'en' + if DefaultTag not in UniLanguageListFiltered: + # check whether language code with primary code equivalent with DefaultTag already in the list, if so, use that + for UniLanguage in UniLanguageList: + if UniLanguage.startswith('en-') or UniLanguage.startswith('eng-'): + if UniLanguage not in UniLanguageListFiltered: + UniLanguageListFiltered += [UniLanguage] + break + else: + UniLanguageListFiltered += [DefaultTag] + return UniLanguageListFiltered + ## Create content of .c file # @@ -293,10 +307,11 @@ def CreateCFileStringValue(Value): # @param UniObjectClass A UniObjectClass instance # @param IsCompatibleMode Compatible mode # @param UniBinBuffer UniBinBuffer to contain UniBinary data. +# @param FilterInfo Platform language filter information # # @retval Str: A string of .c file content # -def CreateCFileContent(BaseName, UniObjectClass, IsCompatibleMode, UniBinBuffer=None): +def CreateCFileContent(BaseName, UniObjectClass, IsCompatibleMode, UniBinBuffer, FilterInfo): # # Init array length # @@ -304,25 +319,40 @@ def CreateCFileContent(BaseName, UniObjectClass, IsCompatibleMode, UniBinBuffer= Str = '' Offset = 0 + EDK2Module = FilterInfo[0] + if EDK2Module: + LanguageFilterList = FilterInfo[1] + else: + # EDK module is using ISO639-2 format filter, convert to the RFC4646 format + LanguageFilterList = [LangConvTable.get(F.lower()) for F in FilterInfo[1]] + + UniLanguageList = [] + for IndexI in range(len(UniObjectClass.LanguageDef)): + UniLanguageList += [UniObjectClass.LanguageDef[IndexI][0]] + + UniLanguageListFiltered = GetFilteredLanguage(UniLanguageList, LanguageFilterList) + + # # Create lines for each language's strings # for IndexI in range(len(UniObjectClass.LanguageDef)): Language = UniObjectClass.LanguageDef[IndexI][0] - LangPrintName = UniObjectClass.LanguageDef[IndexI][1] - + if Language not in UniLanguageListFiltered: + continue + StringBuffer = StringIO() StrStringValue = '' ArrayLength = 0 NumberOfUseOtherLangDef = 0 Index = 0 for IndexJ in range(1, len(UniObjectClass.OrderedStringList[UniObjectClass.LanguageDef[IndexI][0]])): - Item = UniObjectClass.FindByToken(IndexJ, Language) + Item = UniObjectClass.OrderedStringListByToken[Language][IndexJ] + Name = Item.StringName Value = Item.StringValueByteList Referenced = Item.Referenced Token = Item.Token - Length = Item.Length UseOtherLangDef = Item.UseOtherLangDef if UseOtherLangDef != '' and Referenced: @@ -380,14 +410,14 @@ def CreateCFileContent(BaseName, UniObjectClass, IsCompatibleMode, UniBinBuffer= if UniBinBuffer: CreateBinBuffer (UniBinBuffer, List) UniBinBuffer.write (StringBuffer.getvalue()) - UniBinBuffer.write (pack("B", int(EFI_HII_SIBT_END,16))) + UniBinBuffer.write (pack("B", int(EFI_HII_SIBT_END, 16))) StringBuffer.close() # # Create line for string variable name # "unsigned char $(BaseName)Strings[] = {" # - AllStr = WriteLine('', CHAR_ARRAY_DEFIN + ' ' + BaseName + COMMON_FILE_NAME + '[] = {\n' ) + AllStr = WriteLine('', CHAR_ARRAY_DEFIN + ' ' + BaseName + COMMON_FILE_NAME + '[] = {\n') if IsCompatibleMode: # @@ -428,13 +458,13 @@ def CreateCFileEnd(): # @param BaseName: The basename of strings # @param UniObjectClass A UniObjectClass instance # @param IsCompatibleMode Compatible Mode +# @param FilterInfo Platform language filter information # -# @retval CFile: A string of complete .c file +# @retval CFile: A string of complete .c file # -def CreateCFile(BaseName, UniObjectClass, IsCompatibleMode): +def CreateCFile(BaseName, UniObjectClass, IsCompatibleMode, FilterInfo): CFile = '' - #CFile = WriteLine(CFile, CreateCFileHeader()) - CFile = WriteLine(CFile, CreateCFileContent(BaseName, UniObjectClass, IsCompatibleMode)) + CFile = WriteLine(CFile, CreateCFileContent(BaseName, UniObjectClass, IsCompatibleMode, None, FilterInfo)) CFile = WriteLine(CFile, CreateCFileEnd()) return CFile @@ -448,11 +478,11 @@ def CreateCFile(BaseName, UniObjectClass, IsCompatibleMode): # @retval FileList: A list of all files found # def GetFileList(SourceFileList, IncludeList, SkipList): - if IncludeList == None: + if IncludeList is None: EdkLogger.error("UnicodeStringGather", AUTOGEN_ERROR, "Include path for unicode file is not defined") FileList = [] - if SkipList == None: + if SkipList is None: SkipList = [] for File in SourceFileList: @@ -501,11 +531,7 @@ def SearchString(UniObjectClass, FileList, IsCompatibleMode): if os.path.isfile(File): Lines = open(File, 'r') for Line in Lines: - if not IsCompatibleMode: - StringTokenList = STRING_TOKEN.findall(Line) - else: - StringTokenList = COMPATIBLE_STRING_TOKEN.findall(Line) - for StrName in StringTokenList: + for StrName in STRING_TOKEN.findall(Line): EdkLogger.debug(EdkLogger.DEBUG_5, "Found string identifier: " + StrName) UniObjectClass.SetStringReferenced(StrName) @@ -518,10 +544,7 @@ def SearchString(UniObjectClass, FileList, IsCompatibleMode): # This function is used for UEFI2.1 spec # # -def GetStringFiles(UniFilList, SourceFileList, IncludeList, IncludePathList, SkipList, BaseName, IsCompatibleMode = False, ShellMode = False, UniGenCFlag = True, UniGenBinBuffer = None): - Status = True - ErrorMessage = '' - +def GetStringFiles(UniFilList, SourceFileList, IncludeList, IncludePathList, SkipList, BaseName, IsCompatibleMode = False, ShellMode = False, UniGenCFlag = True, UniGenBinBuffer = None, FilterInfo = [True, []]): if len(UniFilList) > 0: if ShellMode: # @@ -540,9 +563,9 @@ def GetStringFiles(UniFilList, SourceFileList, IncludeList, IncludePathList, Ski HFile = CreateHFile(BaseName, Uni, IsCompatibleMode, UniGenCFlag) CFile = None if IsCompatibleMode or UniGenCFlag: - CFile = CreateCFile(BaseName, Uni, IsCompatibleMode) + CFile = CreateCFile(BaseName, Uni, IsCompatibleMode, FilterInfo) if UniGenBinBuffer: - CreateCFileContent(BaseName, Uni, IsCompatibleMode, UniGenBinBuffer) + CreateCFileContent(BaseName, Uni, IsCompatibleMode, UniGenBinBuffer, FilterInfo) return HFile, CFile @@ -550,13 +573,13 @@ def GetStringFiles(UniFilList, SourceFileList, IncludeList, IncludePathList, Ski # Write an item # def Write(Target, Item): - return Target + Item + return ''.join([Target, Item]) # # Write an item with a break line # def WriteLine(Target, Item): - return Target + Item + '\n' + return ''.join([Target, Item, '\n']) # This acts like the main() function for the script, unless it is 'import'ed into another # script.