197fa0ee9b1cffbb4b97ee35365afa7afcf50e174Yingke Liu## @file
297fa0ee9b1cffbb4b97ee35365afa7afcf50e174Yingke Liu# This file is used to collect all defined strings in multiple uni files
397fa0ee9b1cffbb4b97ee35365afa7afcf50e174Yingke Liu#
471f02911b176657c1c8dc952f93a022719ea878aCecil Sheng#
571f02911b176657c1c8dc952f93a022719ea878aCecil Sheng# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.<BR>
671f02911b176657c1c8dc952f93a022719ea878aCecil Sheng#
7d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
840d841f6a8f84e75409178e19e69b95e01bada0flgao# This program and the accompanying materials
930fdf1140b8d1ce93f3821d986fa165552023440lgao# are licensed and made available under the terms and conditions of the BSD License
1030fdf1140b8d1ce93f3821d986fa165552023440lgao# which accompanies this distribution.  The full text of the license may be found at
1130fdf1140b8d1ce93f3821d986fa165552023440lgao# http://opensource.org/licenses/bsd-license.php
1230fdf1140b8d1ce93f3821d986fa165552023440lgao#
1330fdf1140b8d1ce93f3821d986fa165552023440lgao# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
1430fdf1140b8d1ce93f3821d986fa165552023440lgao# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
1530fdf1140b8d1ce93f3821d986fa165552023440lgao
1630fdf1140b8d1ce93f3821d986fa165552023440lgao##
1730fdf1140b8d1ce93f3821d986fa165552023440lgao# Import Modules
1830fdf1140b8d1ce93f3821d986fa165552023440lgao#
191be2ed90a20618d71ddf34b8a07d038da0b36854Hess Chenimport Common.LongFilePathOs as os, codecs, re
2040d841f6a8f84e75409178e19e69b95e01bada0flgaoimport distutils.util
2130fdf1140b8d1ce93f3821d986fa165552023440lgaoimport Common.EdkLogger as EdkLogger
22d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justenimport StringIO
2330fdf1140b8d1ce93f3821d986fa165552023440lgaofrom Common.BuildToolError import *
2430fdf1140b8d1ce93f3821d986fa165552023440lgaofrom Common.String import GetLineNo
2530fdf1140b8d1ce93f3821d986fa165552023440lgaofrom Common.Misc import PathClass
261be2ed90a20618d71ddf34b8a07d038da0b36854Hess Chenfrom Common.LongFilePathSupport import LongFilePath
2730fdf1140b8d1ce93f3821d986fa165552023440lgao##
2830fdf1140b8d1ce93f3821d986fa165552023440lgao# Static definitions
2930fdf1140b8d1ce93f3821d986fa165552023440lgao#
3030fdf1140b8d1ce93f3821d986fa165552023440lgaoUNICODE_WIDE_CHAR = u'\\wide'
3130fdf1140b8d1ce93f3821d986fa165552023440lgaoUNICODE_NARROW_CHAR = u'\\narrow'
3230fdf1140b8d1ce93f3821d986fa165552023440lgaoUNICODE_NON_BREAKING_CHAR = u'\\nbr'
3330fdf1140b8d1ce93f3821d986fa165552023440lgaoUNICODE_UNICODE_CR = '\r'
3430fdf1140b8d1ce93f3821d986fa165552023440lgaoUNICODE_UNICODE_LF = '\n'
3530fdf1140b8d1ce93f3821d986fa165552023440lgao
3630fdf1140b8d1ce93f3821d986fa165552023440lgaoNARROW_CHAR = u'\uFFF0'
3730fdf1140b8d1ce93f3821d986fa165552023440lgaoWIDE_CHAR = u'\uFFF1'
3830fdf1140b8d1ce93f3821d986fa165552023440lgaoNON_BREAKING_CHAR = u'\uFFF2'
3930fdf1140b8d1ce93f3821d986fa165552023440lgaoCR = u'\u000D'
4030fdf1140b8d1ce93f3821d986fa165552023440lgaoLF = u'\u000A'
4130fdf1140b8d1ce93f3821d986fa165552023440lgaoNULL = u'\u0000'
4230fdf1140b8d1ce93f3821d986fa165552023440lgaoTAB = u'\t'
4371f02911b176657c1c8dc952f93a022719ea878aCecil ShengBACK_SLASH_PLACEHOLDER = u'\u0006'
4430fdf1140b8d1ce93f3821d986fa165552023440lgao
4530fdf1140b8d1ce93f3821d986fa165552023440lgaogIncludePattern = re.compile("^#include +[\"<]+([^\"< >]+)[>\"]+$", re.MULTILINE | re.UNICODE)
4630fdf1140b8d1ce93f3821d986fa165552023440lgao
4730fdf1140b8d1ce93f3821d986fa165552023440lgao## Convert a python unicode string to a normal string
4830fdf1140b8d1ce93f3821d986fa165552023440lgao#
4930fdf1140b8d1ce93f3821d986fa165552023440lgao# Convert a python unicode string to a normal string
5030fdf1140b8d1ce93f3821d986fa165552023440lgao# UniToStr(u'I am a string') is 'I am a string'
5130fdf1140b8d1ce93f3821d986fa165552023440lgao#
5230fdf1140b8d1ce93f3821d986fa165552023440lgao# @param Uni:  The python unicode string
5330fdf1140b8d1ce93f3821d986fa165552023440lgao#
5430fdf1140b8d1ce93f3821d986fa165552023440lgao# @retval:     The formatted normal string
5530fdf1140b8d1ce93f3821d986fa165552023440lgao#
5630fdf1140b8d1ce93f3821d986fa165552023440lgaodef UniToStr(Uni):
5730fdf1140b8d1ce93f3821d986fa165552023440lgao    return repr(Uni)[2:-1]
5830fdf1140b8d1ce93f3821d986fa165552023440lgao
5930fdf1140b8d1ce93f3821d986fa165552023440lgao## Convert a unicode string to a Hex list
6030fdf1140b8d1ce93f3821d986fa165552023440lgao#
6130fdf1140b8d1ce93f3821d986fa165552023440lgao# Convert a unicode string to a Hex list
6230fdf1140b8d1ce93f3821d986fa165552023440lgao# UniToHexList('ABC') is ['0x41', '0x00', '0x42', '0x00', '0x43', '0x00']
6330fdf1140b8d1ce93f3821d986fa165552023440lgao#
6430fdf1140b8d1ce93f3821d986fa165552023440lgao# @param Uni:    The python unicode string
6530fdf1140b8d1ce93f3821d986fa165552023440lgao#
6630fdf1140b8d1ce93f3821d986fa165552023440lgao# @retval List:  The formatted hex list
6730fdf1140b8d1ce93f3821d986fa165552023440lgao#
6830fdf1140b8d1ce93f3821d986fa165552023440lgaodef UniToHexList(Uni):
6930fdf1140b8d1ce93f3821d986fa165552023440lgao    List = []
7030fdf1140b8d1ce93f3821d986fa165552023440lgao    for Item in Uni:
7130fdf1140b8d1ce93f3821d986fa165552023440lgao        Temp = '%04X' % ord(Item)
7230fdf1140b8d1ce93f3821d986fa165552023440lgao        List.append('0x' + Temp[2:4])
7330fdf1140b8d1ce93f3821d986fa165552023440lgao        List.append('0x' + Temp[0:2])
7430fdf1140b8d1ce93f3821d986fa165552023440lgao    return List
7530fdf1140b8d1ce93f3821d986fa165552023440lgao
7630fdf1140b8d1ce93f3821d986fa165552023440lgaoLangConvTable = {'eng':'en', 'fra':'fr', \
7730fdf1140b8d1ce93f3821d986fa165552023440lgao                 'aar':'aa', 'abk':'ab', 'ave':'ae', 'afr':'af', 'aka':'ak', 'amh':'am', \
7830fdf1140b8d1ce93f3821d986fa165552023440lgao                 'arg':'an', 'ara':'ar', 'asm':'as', 'ava':'av', 'aym':'ay', 'aze':'az', \
7930fdf1140b8d1ce93f3821d986fa165552023440lgao                 'bak':'ba', 'bel':'be', 'bul':'bg', 'bih':'bh', 'bis':'bi', 'bam':'bm', \
8030fdf1140b8d1ce93f3821d986fa165552023440lgao                 'ben':'bn', 'bod':'bo', 'bre':'br', 'bos':'bs', 'cat':'ca', 'che':'ce', \
8130fdf1140b8d1ce93f3821d986fa165552023440lgao                 'cha':'ch', 'cos':'co', 'cre':'cr', 'ces':'cs', 'chu':'cu', 'chv':'cv', \
8230fdf1140b8d1ce93f3821d986fa165552023440lgao                 'cym':'cy', 'dan':'da', 'deu':'de', 'div':'dv', 'dzo':'dz', 'ewe':'ee', \
8330fdf1140b8d1ce93f3821d986fa165552023440lgao                 'ell':'el', 'epo':'eo', 'spa':'es', 'est':'et', 'eus':'eu', 'fas':'fa', \
8430fdf1140b8d1ce93f3821d986fa165552023440lgao                 'ful':'ff', 'fin':'fi', 'fij':'fj', 'fao':'fo', 'fry':'fy', 'gle':'ga', \
8530fdf1140b8d1ce93f3821d986fa165552023440lgao                 'gla':'gd', 'glg':'gl', 'grn':'gn', 'guj':'gu', 'glv':'gv', 'hau':'ha', \
8630fdf1140b8d1ce93f3821d986fa165552023440lgao                 'heb':'he', 'hin':'hi', 'hmo':'ho', 'hrv':'hr', 'hat':'ht', 'hun':'hu', \
8730fdf1140b8d1ce93f3821d986fa165552023440lgao                 'hye':'hy', 'her':'hz', 'ina':'ia', 'ind':'id', 'ile':'ie', 'ibo':'ig', \
8830fdf1140b8d1ce93f3821d986fa165552023440lgao                 'iii':'ii', 'ipk':'ik', 'ido':'io', 'isl':'is', 'ita':'it', 'iku':'iu', \
8930fdf1140b8d1ce93f3821d986fa165552023440lgao                 'jpn':'ja', 'jav':'jv', 'kat':'ka', 'kon':'kg', 'kik':'ki', 'kua':'kj', \
9030fdf1140b8d1ce93f3821d986fa165552023440lgao                 'kaz':'kk', 'kal':'kl', 'khm':'km', 'kan':'kn', 'kor':'ko', 'kau':'kr', \
9130fdf1140b8d1ce93f3821d986fa165552023440lgao                 'kas':'ks', 'kur':'ku', 'kom':'kv', 'cor':'kw', 'kir':'ky', 'lat':'la', \
9230fdf1140b8d1ce93f3821d986fa165552023440lgao                 'ltz':'lb', 'lug':'lg', 'lim':'li', 'lin':'ln', 'lao':'lo', 'lit':'lt', \
9330fdf1140b8d1ce93f3821d986fa165552023440lgao                 'lub':'lu', 'lav':'lv', 'mlg':'mg', 'mah':'mh', 'mri':'mi', 'mkd':'mk', \
9430fdf1140b8d1ce93f3821d986fa165552023440lgao                 'mal':'ml', 'mon':'mn', 'mar':'mr', 'msa':'ms', 'mlt':'mt', 'mya':'my', \
9530fdf1140b8d1ce93f3821d986fa165552023440lgao                 'nau':'na', 'nob':'nb', 'nde':'nd', 'nep':'ne', 'ndo':'ng', 'nld':'nl', \
9630fdf1140b8d1ce93f3821d986fa165552023440lgao                 'nno':'nn', 'nor':'no', 'nbl':'nr', 'nav':'nv', 'nya':'ny', 'oci':'oc', \
9730fdf1140b8d1ce93f3821d986fa165552023440lgao                 'oji':'oj', 'orm':'om', 'ori':'or', 'oss':'os', 'pan':'pa', 'pli':'pi', \
9830fdf1140b8d1ce93f3821d986fa165552023440lgao                 'pol':'pl', 'pus':'ps', 'por':'pt', 'que':'qu', 'roh':'rm', 'run':'rn', \
9930fdf1140b8d1ce93f3821d986fa165552023440lgao                 'ron':'ro', 'rus':'ru', 'kin':'rw', 'san':'sa', 'srd':'sc', 'snd':'sd', \
10030fdf1140b8d1ce93f3821d986fa165552023440lgao                 'sme':'se', 'sag':'sg', 'sin':'si', 'slk':'sk', 'slv':'sl', 'smo':'sm', \
10130fdf1140b8d1ce93f3821d986fa165552023440lgao                 'sna':'sn', 'som':'so', 'sqi':'sq', 'srp':'sr', 'ssw':'ss', 'sot':'st', \
10230fdf1140b8d1ce93f3821d986fa165552023440lgao                 'sun':'su', 'swe':'sv', 'swa':'sw', 'tam':'ta', 'tel':'te', 'tgk':'tg', \
10330fdf1140b8d1ce93f3821d986fa165552023440lgao                 'tha':'th', 'tir':'ti', 'tuk':'tk', 'tgl':'tl', 'tsn':'tn', 'ton':'to', \
10430fdf1140b8d1ce93f3821d986fa165552023440lgao                 'tur':'tr', 'tso':'ts', 'tat':'tt', 'twi':'tw', 'tah':'ty', 'uig':'ug', \
10530fdf1140b8d1ce93f3821d986fa165552023440lgao                 'ukr':'uk', 'urd':'ur', 'uzb':'uz', 'ven':'ve', 'vie':'vi', 'vol':'vo', \
10630fdf1140b8d1ce93f3821d986fa165552023440lgao                 'wln':'wa', 'wol':'wo', 'xho':'xh', 'yid':'yi', 'yor':'yo', 'zha':'za', \
10730fdf1140b8d1ce93f3821d986fa165552023440lgao                 'zho':'zh', 'zul':'zu'}
10830fdf1140b8d1ce93f3821d986fa165552023440lgao
10930fdf1140b8d1ce93f3821d986fa165552023440lgao## GetLanguageCode
11030fdf1140b8d1ce93f3821d986fa165552023440lgao#
11130fdf1140b8d1ce93f3821d986fa165552023440lgao# Check the language code read from .UNI file and convert ISO 639-2 codes to RFC 4646 codes if appropriate
11230fdf1140b8d1ce93f3821d986fa165552023440lgao# ISO 639-2 language codes supported in compatiblity mode
11330fdf1140b8d1ce93f3821d986fa165552023440lgao# RFC 4646 language codes supported in native mode
11430fdf1140b8d1ce93f3821d986fa165552023440lgao#
11530fdf1140b8d1ce93f3821d986fa165552023440lgao# @param LangName:   Language codes read from .UNI file
11630fdf1140b8d1ce93f3821d986fa165552023440lgao#
11730fdf1140b8d1ce93f3821d986fa165552023440lgao# @retval LangName:  Valid lanugage code in RFC 4646 format or None
11830fdf1140b8d1ce93f3821d986fa165552023440lgao#
11930fdf1140b8d1ce93f3821d986fa165552023440lgaodef GetLanguageCode(LangName, IsCompatibleMode, File):
12030fdf1140b8d1ce93f3821d986fa165552023440lgao    global LangConvTable
12130fdf1140b8d1ce93f3821d986fa165552023440lgao
12230fdf1140b8d1ce93f3821d986fa165552023440lgao    length = len(LangName)
12330fdf1140b8d1ce93f3821d986fa165552023440lgao    if IsCompatibleMode:
12430fdf1140b8d1ce93f3821d986fa165552023440lgao        if length == 3 and LangName.isalpha():
12530fdf1140b8d1ce93f3821d986fa165552023440lgao            TempLangName = LangConvTable.get(LangName.lower())
12630fdf1140b8d1ce93f3821d986fa165552023440lgao            if TempLangName != None:
127da92f27632d2c89fa8726948ac9b02461ca8b61elgao                return TempLangName
12830fdf1140b8d1ce93f3821d986fa165552023440lgao            return LangName
12930fdf1140b8d1ce93f3821d986fa165552023440lgao        else:
13030fdf1140b8d1ce93f3821d986fa165552023440lgao            EdkLogger.error("Unicode File Parser", FORMAT_INVALID, "Invalid ISO 639-2 language code : %s" % LangName, File)
13130fdf1140b8d1ce93f3821d986fa165552023440lgao
13240d841f6a8f84e75409178e19e69b95e01bada0flgao    if (LangName[0] == 'X' or LangName[0] == 'x') and LangName[1] == '-':
13340d841f6a8f84e75409178e19e69b95e01bada0flgao        return LangName
13430fdf1140b8d1ce93f3821d986fa165552023440lgao    if length == 2:
13530fdf1140b8d1ce93f3821d986fa165552023440lgao        if LangName.isalpha():
13630fdf1140b8d1ce93f3821d986fa165552023440lgao            return LangName
13730fdf1140b8d1ce93f3821d986fa165552023440lgao    elif length == 3:
13830fdf1140b8d1ce93f3821d986fa165552023440lgao        if LangName.isalpha() and LangConvTable.get(LangName.lower()) == None:
13930fdf1140b8d1ce93f3821d986fa165552023440lgao            return LangName
14030fdf1140b8d1ce93f3821d986fa165552023440lgao    elif length == 5:
14130fdf1140b8d1ce93f3821d986fa165552023440lgao        if LangName[0:2].isalpha() and LangName[2] == '-':
14230fdf1140b8d1ce93f3821d986fa165552023440lgao            return LangName
14330fdf1140b8d1ce93f3821d986fa165552023440lgao    elif length >= 6:
14430fdf1140b8d1ce93f3821d986fa165552023440lgao        if LangName[0:2].isalpha() and LangName[2] == '-':
14530fdf1140b8d1ce93f3821d986fa165552023440lgao            return LangName
14630fdf1140b8d1ce93f3821d986fa165552023440lgao        if LangName[0:3].isalpha() and LangConvTable.get(LangName.lower()) == None and LangName[3] == '-':
14730fdf1140b8d1ce93f3821d986fa165552023440lgao            return LangName
14830fdf1140b8d1ce93f3821d986fa165552023440lgao
14930fdf1140b8d1ce93f3821d986fa165552023440lgao    EdkLogger.error("Unicode File Parser", FORMAT_INVALID, "Invalid RFC 4646 language code : %s" % LangName, File)
15030fdf1140b8d1ce93f3821d986fa165552023440lgao
151d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen## Ucs2Codec
152d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen#
153d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen# This is only a partial codec implementation. It only supports
154d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen# encoding, and is primarily used to check that all the characters are
155d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen# valid for UCS-2.
156d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen#
157d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justenclass Ucs2Codec(codecs.Codec):
158d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen    def __init__(self):
159d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen        self.__utf16 = codecs.lookup('utf-16')
160d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen
161d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen    def encode(self, input, errors='strict'):
162d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen        for Char in input:
163d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen            CodePoint = ord(Char)
164d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen            if CodePoint >= 0xd800 and CodePoint <= 0xdfff:
165d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen                raise ValueError("Code Point is in range reserved for " +
166d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen                                 "UTF-16 surrogate pairs")
167d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen            elif CodePoint > 0xffff:
168d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen                raise ValueError("Code Point too large to encode in UCS-2")
169d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen        return self.__utf16.encode(input)
170d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen
171d80e451b187c9d33cbd771253fbd5119670f75c6Jordan JustenTheUcs2Codec = Ucs2Codec()
172d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justendef Ucs2Search(name):
173d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen    if name == 'ucs-2':
174d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen        return codecs.CodecInfo(
175d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen            name=name,
176d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen            encode=TheUcs2Codec.encode,
177d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen            decode=TheUcs2Codec.decode)
178d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen    else:
179d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen        return None
180d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justencodecs.register(Ucs2Search)
181d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen
18230fdf1140b8d1ce93f3821d986fa165552023440lgao## StringDefClassObject
18330fdf1140b8d1ce93f3821d986fa165552023440lgao#
18430fdf1140b8d1ce93f3821d986fa165552023440lgao# A structure for language definition
18530fdf1140b8d1ce93f3821d986fa165552023440lgao#
18630fdf1140b8d1ce93f3821d986fa165552023440lgaoclass StringDefClassObject(object):
18730fdf1140b8d1ce93f3821d986fa165552023440lgao    def __init__(self, Name = None, Value = None, Referenced = False, Token = None, UseOtherLangDef = ''):
18830fdf1140b8d1ce93f3821d986fa165552023440lgao        self.StringName = ''
18930fdf1140b8d1ce93f3821d986fa165552023440lgao        self.StringNameByteList = []
19030fdf1140b8d1ce93f3821d986fa165552023440lgao        self.StringValue = ''
19130fdf1140b8d1ce93f3821d986fa165552023440lgao        self.StringValueByteList = ''
19230fdf1140b8d1ce93f3821d986fa165552023440lgao        self.Token = 0
19330fdf1140b8d1ce93f3821d986fa165552023440lgao        self.Referenced = Referenced
19430fdf1140b8d1ce93f3821d986fa165552023440lgao        self.UseOtherLangDef = UseOtherLangDef
19530fdf1140b8d1ce93f3821d986fa165552023440lgao        self.Length = 0
19630fdf1140b8d1ce93f3821d986fa165552023440lgao
19730fdf1140b8d1ce93f3821d986fa165552023440lgao        if Name != None:
19830fdf1140b8d1ce93f3821d986fa165552023440lgao            self.StringName = Name
19930fdf1140b8d1ce93f3821d986fa165552023440lgao            self.StringNameByteList = UniToHexList(Name)
20030fdf1140b8d1ce93f3821d986fa165552023440lgao        if Value != None:
20130fdf1140b8d1ce93f3821d986fa165552023440lgao            self.StringValue = Value + u'\x00'        # Add a NULL at string tail
20230fdf1140b8d1ce93f3821d986fa165552023440lgao            self.StringValueByteList = UniToHexList(self.StringValue)
20330fdf1140b8d1ce93f3821d986fa165552023440lgao            self.Length = len(self.StringValueByteList)
20430fdf1140b8d1ce93f3821d986fa165552023440lgao        if Token != None:
20530fdf1140b8d1ce93f3821d986fa165552023440lgao            self.Token = Token
20630fdf1140b8d1ce93f3821d986fa165552023440lgao
20730fdf1140b8d1ce93f3821d986fa165552023440lgao    def __str__(self):
20830fdf1140b8d1ce93f3821d986fa165552023440lgao        return repr(self.StringName) + ' ' + \
20930fdf1140b8d1ce93f3821d986fa165552023440lgao               repr(self.Token) + ' ' + \
21030fdf1140b8d1ce93f3821d986fa165552023440lgao               repr(self.Referenced) + ' ' + \
21130fdf1140b8d1ce93f3821d986fa165552023440lgao               repr(self.StringValue) + ' ' + \
21230fdf1140b8d1ce93f3821d986fa165552023440lgao               repr(self.UseOtherLangDef)
21330fdf1140b8d1ce93f3821d986fa165552023440lgao
214756ad8f8e9d3e345f1883546e2a3125203e234aalgao    def UpdateValue(self, Value = None):
215756ad8f8e9d3e345f1883546e2a3125203e234aalgao        if Value != None:
216756ad8f8e9d3e345f1883546e2a3125203e234aalgao            self.StringValue = Value + u'\x00'        # Add a NULL at string tail
217756ad8f8e9d3e345f1883546e2a3125203e234aalgao            self.StringValueByteList = UniToHexList(self.StringValue)
218756ad8f8e9d3e345f1883546e2a3125203e234aalgao            self.Length = len(self.StringValueByteList)
219756ad8f8e9d3e345f1883546e2a3125203e234aalgao
22030fdf1140b8d1ce93f3821d986fa165552023440lgao## UniFileClassObject
22130fdf1140b8d1ce93f3821d986fa165552023440lgao#
22230fdf1140b8d1ce93f3821d986fa165552023440lgao# A structure for .uni file definition
22330fdf1140b8d1ce93f3821d986fa165552023440lgao#
22430fdf1140b8d1ce93f3821d986fa165552023440lgaoclass UniFileClassObject(object):
225756ad8f8e9d3e345f1883546e2a3125203e234aalgao    def __init__(self, FileList = [], IsCompatibleMode = False, IncludePathList = []):
22630fdf1140b8d1ce93f3821d986fa165552023440lgao        self.FileList = FileList
22730fdf1140b8d1ce93f3821d986fa165552023440lgao        self.Token = 2
22830fdf1140b8d1ce93f3821d986fa165552023440lgao        self.LanguageDef = []                   #[ [u'LanguageIdentifier', u'PrintableName'], ... ]
22930fdf1140b8d1ce93f3821d986fa165552023440lgao        self.OrderedStringList = {}             #{ u'LanguageIdentifier' : [StringDefClassObject]  }
23079b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao        self.OrderedStringDict = {}             #{ u'LanguageIdentifier' : {StringName:(IndexInList)}  }
23179b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao        self.OrderedStringListByToken = {}      #{ u'LanguageIdentifier' : {Token: StringDefClassObject} }
23230fdf1140b8d1ce93f3821d986fa165552023440lgao        self.IsCompatibleMode = IsCompatibleMode
233756ad8f8e9d3e345f1883546e2a3125203e234aalgao        self.IncludePathList = IncludePathList
23430fdf1140b8d1ce93f3821d986fa165552023440lgao        if len(self.FileList) > 0:
23530fdf1140b8d1ce93f3821d986fa165552023440lgao            self.LoadUniFiles(FileList)
23630fdf1140b8d1ce93f3821d986fa165552023440lgao
23730fdf1140b8d1ce93f3821d986fa165552023440lgao    #
23830fdf1140b8d1ce93f3821d986fa165552023440lgao    # Get Language definition
23930fdf1140b8d1ce93f3821d986fa165552023440lgao    #
24030fdf1140b8d1ce93f3821d986fa165552023440lgao    def GetLangDef(self, File, Line):
24140d841f6a8f84e75409178e19e69b95e01bada0flgao        Lang = distutils.util.split_quoted((Line.split(u"//")[0]))
24230fdf1140b8d1ce93f3821d986fa165552023440lgao        if len(Lang) != 3:
24330fdf1140b8d1ce93f3821d986fa165552023440lgao            try:
244d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen                FileIn = self.OpenUniFile(LongFilePath(File.Path))
24530fdf1140b8d1ce93f3821d986fa165552023440lgao            except UnicodeError, X:
24630fdf1140b8d1ce93f3821d986fa165552023440lgao                EdkLogger.error("build", FILE_READ_FAILURE, "File read failure: %s" % str(X), ExtraData=File);
24730fdf1140b8d1ce93f3821d986fa165552023440lgao            except:
24830fdf1140b8d1ce93f3821d986fa165552023440lgao                EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=File);
24930fdf1140b8d1ce93f3821d986fa165552023440lgao            LineNo = GetLineNo(FileIn, Line, False)
25030fdf1140b8d1ce93f3821d986fa165552023440lgao            EdkLogger.error("Unicode File Parser", PARSER_ERROR, "Wrong language definition",
25147fea6afd74af76c7e2a2b03d319b7ac035ac26aYonghong Zhu                            ExtraData="""%s\n\t*Correct format is like '#langdef en-US "English"'""" % Line, File=File, Line=LineNo)
25230fdf1140b8d1ce93f3821d986fa165552023440lgao        else:
25330fdf1140b8d1ce93f3821d986fa165552023440lgao            LangName = GetLanguageCode(Lang[1], self.IsCompatibleMode, self.File)
25440d841f6a8f84e75409178e19e69b95e01bada0flgao            LangPrintName = Lang[2]
25530fdf1140b8d1ce93f3821d986fa165552023440lgao
25630fdf1140b8d1ce93f3821d986fa165552023440lgao        IsLangInDef = False
25730fdf1140b8d1ce93f3821d986fa165552023440lgao        for Item in self.LanguageDef:
25830fdf1140b8d1ce93f3821d986fa165552023440lgao            if Item[0] == LangName:
25930fdf1140b8d1ce93f3821d986fa165552023440lgao                IsLangInDef = True
26030fdf1140b8d1ce93f3821d986fa165552023440lgao                break;
26130fdf1140b8d1ce93f3821d986fa165552023440lgao
26230fdf1140b8d1ce93f3821d986fa165552023440lgao        if not IsLangInDef:
26330fdf1140b8d1ce93f3821d986fa165552023440lgao            self.LanguageDef.append([LangName, LangPrintName])
26430fdf1140b8d1ce93f3821d986fa165552023440lgao
26530fdf1140b8d1ce93f3821d986fa165552023440lgao        #
26630fdf1140b8d1ce93f3821d986fa165552023440lgao        # Add language string
26730fdf1140b8d1ce93f3821d986fa165552023440lgao        #
26830fdf1140b8d1ce93f3821d986fa165552023440lgao        self.AddStringToList(u'$LANGUAGE_NAME', LangName, LangName, 0, True, Index=0)
26930fdf1140b8d1ce93f3821d986fa165552023440lgao        self.AddStringToList(u'$PRINTABLE_LANGUAGE_NAME', LangName, LangPrintName, 1, True, Index=1)
27030fdf1140b8d1ce93f3821d986fa165552023440lgao
271756ad8f8e9d3e345f1883546e2a3125203e234aalgao        if not IsLangInDef:
272756ad8f8e9d3e345f1883546e2a3125203e234aalgao            #
273756ad8f8e9d3e345f1883546e2a3125203e234aalgao            # The found STRING tokens will be added into new language string list
274756ad8f8e9d3e345f1883546e2a3125203e234aalgao            # so that the unique STRING identifier is reserved for all languages in the package list.
275756ad8f8e9d3e345f1883546e2a3125203e234aalgao            #
276756ad8f8e9d3e345f1883546e2a3125203e234aalgao            FirstLangName = self.LanguageDef[0][0]
277756ad8f8e9d3e345f1883546e2a3125203e234aalgao            if LangName != FirstLangName:
278756ad8f8e9d3e345f1883546e2a3125203e234aalgao                for Index in range (2, len (self.OrderedStringList[FirstLangName])):
279756ad8f8e9d3e345f1883546e2a3125203e234aalgao                    Item = self.OrderedStringList[FirstLangName][Index]
280756ad8f8e9d3e345f1883546e2a3125203e234aalgao                    if Item.UseOtherLangDef != '':
281756ad8f8e9d3e345f1883546e2a3125203e234aalgao                        OtherLang = Item.UseOtherLangDef
282756ad8f8e9d3e345f1883546e2a3125203e234aalgao                    else:
283756ad8f8e9d3e345f1883546e2a3125203e234aalgao                        OtherLang = FirstLangName
284756ad8f8e9d3e345f1883546e2a3125203e234aalgao                    self.OrderedStringList[LangName].append (StringDefClassObject(Item.StringName, '', Item.Referenced, Item.Token, OtherLang))
28579b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao                    self.OrderedStringDict[LangName][Item.StringName] = len(self.OrderedStringList[LangName]) - 1
28630fdf1140b8d1ce93f3821d986fa165552023440lgao        return True
28730fdf1140b8d1ce93f3821d986fa165552023440lgao
288d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen    def OpenUniFile(self, FileName):
289d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen        #
290d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen        # Read file
291d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen        #
292d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen        try:
293d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen            UniFile = open(FileName, mode='rb')
294d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen            FileIn = UniFile.read()
295d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen            UniFile.close()
296d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen        except:
297d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen            EdkLogger.Error("build", FILE_OPEN_FAILURE, ExtraData=File)
298d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen
299d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen        #
300be264422c95c781a345978f17b7e80b91f816edaJordan Justen        # Detect Byte Order Mark at beginning of file.  Default to UTF-8
301d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen        #
302be264422c95c781a345978f17b7e80b91f816edaJordan Justen        Encoding = 'utf-8'
303be264422c95c781a345978f17b7e80b91f816edaJordan Justen        if (FileIn.startswith(codecs.BOM_UTF16_BE) or
304be264422c95c781a345978f17b7e80b91f816edaJordan Justen            FileIn.startswith(codecs.BOM_UTF16_LE)):
305be264422c95c781a345978f17b7e80b91f816edaJordan Justen            Encoding = 'utf-16'
306d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen
307d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen        self.VerifyUcs2Data(FileIn, FileName, Encoding)
308d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen
309d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen        UniFile = StringIO.StringIO(FileIn)
310d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen        Info = codecs.lookup(Encoding)
311d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen        (Reader, Writer) = (Info.streamreader, Info.streamwriter)
312d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen        return codecs.StreamReaderWriter(UniFile, Reader, Writer)
313d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen
314d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen    def VerifyUcs2Data(self, FileIn, FileName, Encoding):
315d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen        Ucs2Info = codecs.lookup('ucs-2')
316d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen        #
317d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen        # Convert to unicode
318d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen        #
319d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen        try:
320d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen            FileDecoded = codecs.decode(FileIn, Encoding)
321d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen            Ucs2Info.encode(FileDecoded)
322d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen        except:
323d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen            UniFile = StringIO.StringIO(FileIn)
324d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen            Info = codecs.lookup(Encoding)
325d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen            (Reader, Writer) = (Info.streamreader, Info.streamwriter)
326d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen            File = codecs.StreamReaderWriter(UniFile, Reader, Writer)
327d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen            LineNumber = 0
328d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen            ErrMsg = lambda Encoding, LineNumber: \
329d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen                     '%s contains invalid %s characters on line %d.' % \
330d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen                     (FileName, Encoding, LineNumber)
331d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen            while True:
332d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen                LineNumber = LineNumber + 1
333d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen                try:
334d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen                    Line = File.readline()
335d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen                    if Line == '':
336d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen                        EdkLogger.error('Unicode File Parser', PARSER_ERROR,
337d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen                                        ErrMsg(Encoding, LineNumber))
338d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen                    Ucs2Info.encode(Line)
339d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen                except:
340d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen                    EdkLogger.error('Unicode File Parser', PARSER_ERROR,
341d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen                                    ErrMsg('UCS-2', LineNumber))
342d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen
34330fdf1140b8d1ce93f3821d986fa165552023440lgao    #
34430fdf1140b8d1ce93f3821d986fa165552023440lgao    # Get String name and value
34530fdf1140b8d1ce93f3821d986fa165552023440lgao    #
34630fdf1140b8d1ce93f3821d986fa165552023440lgao    def GetStringObject(self, Item):
34730fdf1140b8d1ce93f3821d986fa165552023440lgao        Language = ''
34830fdf1140b8d1ce93f3821d986fa165552023440lgao        Value = ''
34930fdf1140b8d1ce93f3821d986fa165552023440lgao
35030fdf1140b8d1ce93f3821d986fa165552023440lgao        Name = Item.split()[1]
351b303ea726e1c8ed240dad2bce54821318567eab3lgao        # Check the string name is the upper character
3522bcc713e74b944bb5aefb433ef33fb4002a62d76lgao        if Name != '':
353b303ea726e1c8ed240dad2bce54821318567eab3lgao            MatchString = re.match('[A-Z0-9_]+', Name, re.UNICODE)
354b303ea726e1c8ed240dad2bce54821318567eab3lgao            if MatchString == None or MatchString.end(0) != len(Name):
35547fea6afd74af76c7e2a2b03d319b7ac035ac26aYonghong Zhu                EdkLogger.error('Unicode File Parser', FORMAT_INVALID, 'The string token name %s defined in UNI file %s contains the invalid lower case character.' % (Name, self.File))
35630fdf1140b8d1ce93f3821d986fa165552023440lgao        LanguageList = Item.split(u'#language ')
35730fdf1140b8d1ce93f3821d986fa165552023440lgao        for IndexI in range(len(LanguageList)):
35830fdf1140b8d1ce93f3821d986fa165552023440lgao            if IndexI == 0:
35930fdf1140b8d1ce93f3821d986fa165552023440lgao                continue
36030fdf1140b8d1ce93f3821d986fa165552023440lgao            else:
36130fdf1140b8d1ce93f3821d986fa165552023440lgao                Language = LanguageList[IndexI].split()[0]
36230fdf1140b8d1ce93f3821d986fa165552023440lgao                Value = LanguageList[IndexI][LanguageList[IndexI].find(u'\"') + len(u'\"') : LanguageList[IndexI].rfind(u'\"')] #.replace(u'\r\n', u'')
36330fdf1140b8d1ce93f3821d986fa165552023440lgao                Language = GetLanguageCode(Language, self.IsCompatibleMode, self.File)
36430fdf1140b8d1ce93f3821d986fa165552023440lgao                self.AddStringToList(Name, Language, Value)
36530fdf1140b8d1ce93f3821d986fa165552023440lgao
36630fdf1140b8d1ce93f3821d986fa165552023440lgao    #
36730fdf1140b8d1ce93f3821d986fa165552023440lgao    # Get include file list and load them
36830fdf1140b8d1ce93f3821d986fa165552023440lgao    #
36930fdf1140b8d1ce93f3821d986fa165552023440lgao    def GetIncludeFile(self, Item, Dir):
37030fdf1140b8d1ce93f3821d986fa165552023440lgao        FileName = Item[Item.find(u'#include ') + len(u'#include ') :Item.find(u' ', len(u'#include '))][1:-1]
37130fdf1140b8d1ce93f3821d986fa165552023440lgao        self.LoadUniFile(FileName)
37230fdf1140b8d1ce93f3821d986fa165552023440lgao
37371f02911b176657c1c8dc952f93a022719ea878aCecil Sheng    def StripComments(self, Line):
37471f02911b176657c1c8dc952f93a022719ea878aCecil Sheng        Comment = u'//'
37571f02911b176657c1c8dc952f93a022719ea878aCecil Sheng        CommentPos = Line.find(Comment)
37671f02911b176657c1c8dc952f93a022719ea878aCecil Sheng        while CommentPos >= 0:
37771f02911b176657c1c8dc952f93a022719ea878aCecil Sheng        # if there are non matched quotes before the comment header
37871f02911b176657c1c8dc952f93a022719ea878aCecil Sheng        # then we are in the middle of a string
37971f02911b176657c1c8dc952f93a022719ea878aCecil Sheng        # but we need to ignore the escaped quotes and backslashes.
38071f02911b176657c1c8dc952f93a022719ea878aCecil Sheng            if ((Line.count(u'"', 0, CommentPos) - Line.count(u'\\"', 0, CommentPos)) & 1) == 1:
38171f02911b176657c1c8dc952f93a022719ea878aCecil Sheng                CommentPos = Line.find (Comment, CommentPos + 1)
38271f02911b176657c1c8dc952f93a022719ea878aCecil Sheng            else:
38345265a86142fe8259d2b2ba279b1b7b0da814993Yingke Liu                return Line[:CommentPos].strip()
38445265a86142fe8259d2b2ba279b1b7b0da814993Yingke Liu        return Line.strip()
38571f02911b176657c1c8dc952f93a022719ea878aCecil Sheng
38671f02911b176657c1c8dc952f93a022719ea878aCecil Sheng
38730fdf1140b8d1ce93f3821d986fa165552023440lgao    #
38830fdf1140b8d1ce93f3821d986fa165552023440lgao    # Pre-process before parse .uni file
38930fdf1140b8d1ce93f3821d986fa165552023440lgao    #
39030fdf1140b8d1ce93f3821d986fa165552023440lgao    def PreProcess(self, File):
39130fdf1140b8d1ce93f3821d986fa165552023440lgao        if not os.path.exists(File.Path) or not os.path.isfile(File.Path):
39230fdf1140b8d1ce93f3821d986fa165552023440lgao            EdkLogger.error("Unicode File Parser", FILE_NOT_FOUND, ExtraData=File.Path)
39330fdf1140b8d1ce93f3821d986fa165552023440lgao
39430fdf1140b8d1ce93f3821d986fa165552023440lgao        try:
395d80e451b187c9d33cbd771253fbd5119670f75c6Jordan Justen            FileIn = self.OpenUniFile(LongFilePath(File.Path))
39630fdf1140b8d1ce93f3821d986fa165552023440lgao        except UnicodeError, X:
39730fdf1140b8d1ce93f3821d986fa165552023440lgao            EdkLogger.error("build", FILE_READ_FAILURE, "File read failure: %s" % str(X), ExtraData=File.Path);
39830fdf1140b8d1ce93f3821d986fa165552023440lgao        except:
39930fdf1140b8d1ce93f3821d986fa165552023440lgao            EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=File.Path);
40030fdf1140b8d1ce93f3821d986fa165552023440lgao
40130fdf1140b8d1ce93f3821d986fa165552023440lgao        Lines = []
40230fdf1140b8d1ce93f3821d986fa165552023440lgao        #
40330fdf1140b8d1ce93f3821d986fa165552023440lgao        # Use unique identifier
40430fdf1140b8d1ce93f3821d986fa165552023440lgao        #
40530fdf1140b8d1ce93f3821d986fa165552023440lgao        for Line in FileIn:
40630fdf1140b8d1ce93f3821d986fa165552023440lgao            Line = Line.strip()
40771f02911b176657c1c8dc952f93a022719ea878aCecil Sheng            Line = Line.replace(u'\\\\', BACK_SLASH_PLACEHOLDER)
40871f02911b176657c1c8dc952f93a022719ea878aCecil Sheng            Line = self.StripComments(Line)
40971f02911b176657c1c8dc952f93a022719ea878aCecil Sheng
41030fdf1140b8d1ce93f3821d986fa165552023440lgao            #
41171f02911b176657c1c8dc952f93a022719ea878aCecil Sheng            # Ignore empty line
41230fdf1140b8d1ce93f3821d986fa165552023440lgao            #
41371f02911b176657c1c8dc952f93a022719ea878aCecil Sheng            if len(Line) == 0:
41471f02911b176657c1c8dc952f93a022719ea878aCecil Sheng                continue
415da92f27632d2c89fa8726948ac9b02461ca8b61elgao
41671f02911b176657c1c8dc952f93a022719ea878aCecil Sheng
41730fdf1140b8d1ce93f3821d986fa165552023440lgao            Line = Line.replace(u'/langdef', u'#langdef')
41830fdf1140b8d1ce93f3821d986fa165552023440lgao            Line = Line.replace(u'/string', u'#string')
41930fdf1140b8d1ce93f3821d986fa165552023440lgao            Line = Line.replace(u'/language', u'#language')
42030fdf1140b8d1ce93f3821d986fa165552023440lgao            Line = Line.replace(u'/include', u'#include')
42130fdf1140b8d1ce93f3821d986fa165552023440lgao
42230fdf1140b8d1ce93f3821d986fa165552023440lgao            Line = Line.replace(UNICODE_WIDE_CHAR, WIDE_CHAR)
42330fdf1140b8d1ce93f3821d986fa165552023440lgao            Line = Line.replace(UNICODE_NARROW_CHAR, NARROW_CHAR)
42430fdf1140b8d1ce93f3821d986fa165552023440lgao            Line = Line.replace(UNICODE_NON_BREAKING_CHAR, NON_BREAKING_CHAR)
42530fdf1140b8d1ce93f3821d986fa165552023440lgao
42630fdf1140b8d1ce93f3821d986fa165552023440lgao            Line = Line.replace(u'\\r\\n', CR + LF)
42730fdf1140b8d1ce93f3821d986fa165552023440lgao            Line = Line.replace(u'\\n', CR + LF)
42830fdf1140b8d1ce93f3821d986fa165552023440lgao            Line = Line.replace(u'\\r', CR)
42971f02911b176657c1c8dc952f93a022719ea878aCecil Sheng            Line = Line.replace(u'\\t', u' ')
4308546dfeace040f9f6547cb1b44651a44b8b9670eYingke Liu            Line = Line.replace(u'\t', u' ')
43171f02911b176657c1c8dc952f93a022719ea878aCecil Sheng            Line = Line.replace(u'\\"', u'"')
43271f02911b176657c1c8dc952f93a022719ea878aCecil Sheng            Line = Line.replace(u"\\'", u"'")
43371f02911b176657c1c8dc952f93a022719ea878aCecil Sheng            Line = Line.replace(BACK_SLASH_PLACEHOLDER, u'\\')
4344afd3d042215afe68d00b9ab8c32f063a3a1c03fLiming Gao
43530fdf1140b8d1ce93f3821d986fa165552023440lgao#           if Line.find(u'\\x'):
43630fdf1140b8d1ce93f3821d986fa165552023440lgao#               hex = Line[Line.find(u'\\x') + 2 : Line.find(u'\\x') + 6]
43730fdf1140b8d1ce93f3821d986fa165552023440lgao#               hex = "u'\\u" + hex + "'"
43830fdf1140b8d1ce93f3821d986fa165552023440lgao
43930fdf1140b8d1ce93f3821d986fa165552023440lgao            IncList = gIncludePattern.findall(Line)
44030fdf1140b8d1ce93f3821d986fa165552023440lgao            if len(IncList) == 1:
441756ad8f8e9d3e345f1883546e2a3125203e234aalgao                for Dir in [File.Dir] + self.IncludePathList:
442756ad8f8e9d3e345f1883546e2a3125203e234aalgao                    IncFile = PathClass(str(IncList[0]), Dir)
443756ad8f8e9d3e345f1883546e2a3125203e234aalgao                    if os.path.isfile(IncFile.Path):
444756ad8f8e9d3e345f1883546e2a3125203e234aalgao                        Lines.extend(self.PreProcess(IncFile))
445756ad8f8e9d3e345f1883546e2a3125203e234aalgao                        break
446756ad8f8e9d3e345f1883546e2a3125203e234aalgao                else:
447756ad8f8e9d3e345f1883546e2a3125203e234aalgao                    EdkLogger.error("Unicode File Parser", FILE_NOT_FOUND, Message="Cannot find include file", ExtraData=str(IncList[0]))
44830fdf1140b8d1ce93f3821d986fa165552023440lgao                continue
44930fdf1140b8d1ce93f3821d986fa165552023440lgao
45030fdf1140b8d1ce93f3821d986fa165552023440lgao            Lines.append(Line)
45130fdf1140b8d1ce93f3821d986fa165552023440lgao
45230fdf1140b8d1ce93f3821d986fa165552023440lgao        return Lines
45330fdf1140b8d1ce93f3821d986fa165552023440lgao
45430fdf1140b8d1ce93f3821d986fa165552023440lgao    #
45530fdf1140b8d1ce93f3821d986fa165552023440lgao    # Load a .uni file
45630fdf1140b8d1ce93f3821d986fa165552023440lgao    #
45730fdf1140b8d1ce93f3821d986fa165552023440lgao    def LoadUniFile(self, File = None):
45830fdf1140b8d1ce93f3821d986fa165552023440lgao        if File == None:
45930fdf1140b8d1ce93f3821d986fa165552023440lgao            EdkLogger.error("Unicode File Parser", PARSER_ERROR, 'No unicode file is given')
46030fdf1140b8d1ce93f3821d986fa165552023440lgao        self.File = File
46130fdf1140b8d1ce93f3821d986fa165552023440lgao        #
46230fdf1140b8d1ce93f3821d986fa165552023440lgao        # Process special char in file
46330fdf1140b8d1ce93f3821d986fa165552023440lgao        #
46430fdf1140b8d1ce93f3821d986fa165552023440lgao        Lines = self.PreProcess(File)
46530fdf1140b8d1ce93f3821d986fa165552023440lgao
46630fdf1140b8d1ce93f3821d986fa165552023440lgao        #
46730fdf1140b8d1ce93f3821d986fa165552023440lgao        # Get Unicode Information
46830fdf1140b8d1ce93f3821d986fa165552023440lgao        #
46930fdf1140b8d1ce93f3821d986fa165552023440lgao        for IndexI in range(len(Lines)):
47030fdf1140b8d1ce93f3821d986fa165552023440lgao            Line = Lines[IndexI]
47130fdf1140b8d1ce93f3821d986fa165552023440lgao            if (IndexI + 1) < len(Lines):
47230fdf1140b8d1ce93f3821d986fa165552023440lgao                SecondLine = Lines[IndexI + 1]
47330fdf1140b8d1ce93f3821d986fa165552023440lgao            if (IndexI + 2) < len(Lines):
47430fdf1140b8d1ce93f3821d986fa165552023440lgao                ThirdLine = Lines[IndexI + 2]
47530fdf1140b8d1ce93f3821d986fa165552023440lgao
47630fdf1140b8d1ce93f3821d986fa165552023440lgao            #
47730fdf1140b8d1ce93f3821d986fa165552023440lgao            # Get Language def information
47830fdf1140b8d1ce93f3821d986fa165552023440lgao            #
47930fdf1140b8d1ce93f3821d986fa165552023440lgao            if Line.find(u'#langdef ') >= 0:
48030fdf1140b8d1ce93f3821d986fa165552023440lgao                self.GetLangDef(File, Line)
48130fdf1140b8d1ce93f3821d986fa165552023440lgao                continue
48230fdf1140b8d1ce93f3821d986fa165552023440lgao
48330fdf1140b8d1ce93f3821d986fa165552023440lgao            Name = ''
48430fdf1140b8d1ce93f3821d986fa165552023440lgao            Language = ''
48530fdf1140b8d1ce93f3821d986fa165552023440lgao            Value = ''
48630fdf1140b8d1ce93f3821d986fa165552023440lgao            #
48730fdf1140b8d1ce93f3821d986fa165552023440lgao            # Get string def information format 1 as below
48830fdf1140b8d1ce93f3821d986fa165552023440lgao            #
48930fdf1140b8d1ce93f3821d986fa165552023440lgao            #     #string MY_STRING_1
49030fdf1140b8d1ce93f3821d986fa165552023440lgao            #     #language eng
49130fdf1140b8d1ce93f3821d986fa165552023440lgao            #     My first English string line 1
49230fdf1140b8d1ce93f3821d986fa165552023440lgao            #     My first English string line 2
49330fdf1140b8d1ce93f3821d986fa165552023440lgao            #     #string MY_STRING_1
49430fdf1140b8d1ce93f3821d986fa165552023440lgao            #     #language spa
49530fdf1140b8d1ce93f3821d986fa165552023440lgao            #     Mi segunda secuencia 1
49630fdf1140b8d1ce93f3821d986fa165552023440lgao            #     Mi segunda secuencia 2
49730fdf1140b8d1ce93f3821d986fa165552023440lgao            #
49830fdf1140b8d1ce93f3821d986fa165552023440lgao            if Line.find(u'#string ') >= 0 and Line.find(u'#language ') < 0 and \
49930fdf1140b8d1ce93f3821d986fa165552023440lgao                SecondLine.find(u'#string ') < 0 and SecondLine.find(u'#language ') >= 0 and \
50030fdf1140b8d1ce93f3821d986fa165552023440lgao                ThirdLine.find(u'#string ') < 0 and ThirdLine.find(u'#language ') < 0:
50130fdf1140b8d1ce93f3821d986fa165552023440lgao                Name = Line[Line.find(u'#string ') + len(u'#string ') : ].strip(' ')
50230fdf1140b8d1ce93f3821d986fa165552023440lgao                Language = SecondLine[SecondLine.find(u'#language ') + len(u'#language ') : ].strip(' ')
50330fdf1140b8d1ce93f3821d986fa165552023440lgao                for IndexJ in range(IndexI + 2, len(Lines)):
50430fdf1140b8d1ce93f3821d986fa165552023440lgao                    if Lines[IndexJ].find(u'#string ') < 0 and Lines[IndexJ].find(u'#language ') < 0:
50530fdf1140b8d1ce93f3821d986fa165552023440lgao                        Value = Value + Lines[IndexJ]
50630fdf1140b8d1ce93f3821d986fa165552023440lgao                    else:
50730fdf1140b8d1ce93f3821d986fa165552023440lgao                        IndexI = IndexJ
50830fdf1140b8d1ce93f3821d986fa165552023440lgao                        break
50930fdf1140b8d1ce93f3821d986fa165552023440lgao                # Value = Value.replace(u'\r\n', u'')
51030fdf1140b8d1ce93f3821d986fa165552023440lgao                Language = GetLanguageCode(Language, self.IsCompatibleMode, self.File)
511b303ea726e1c8ed240dad2bce54821318567eab3lgao                # Check the string name is the upper character
512b303ea726e1c8ed240dad2bce54821318567eab3lgao                if not self.IsCompatibleMode and Name != '':
513b303ea726e1c8ed240dad2bce54821318567eab3lgao                    MatchString = re.match('[A-Z0-9_]+', Name, re.UNICODE)
514b303ea726e1c8ed240dad2bce54821318567eab3lgao                    if MatchString == None or MatchString.end(0) != len(Name):
51547fea6afd74af76c7e2a2b03d319b7ac035ac26aYonghong Zhu                        EdkLogger.error('Unicode File Parser', FORMAT_INVALID, 'The string token name %s defined in UNI file %s contains the invalid lower case character.' % (Name, self.File))
51630fdf1140b8d1ce93f3821d986fa165552023440lgao                self.AddStringToList(Name, Language, Value)
51730fdf1140b8d1ce93f3821d986fa165552023440lgao                continue
51830fdf1140b8d1ce93f3821d986fa165552023440lgao
51930fdf1140b8d1ce93f3821d986fa165552023440lgao            #
52030fdf1140b8d1ce93f3821d986fa165552023440lgao            # Get string def information format 2 as below
52130fdf1140b8d1ce93f3821d986fa165552023440lgao            #
52230fdf1140b8d1ce93f3821d986fa165552023440lgao            #     #string MY_STRING_1     #language eng     "My first English string line 1"
52330fdf1140b8d1ce93f3821d986fa165552023440lgao            #                                               "My first English string line 2"
52430fdf1140b8d1ce93f3821d986fa165552023440lgao            #                             #language spa     "Mi segunda secuencia 1"
52530fdf1140b8d1ce93f3821d986fa165552023440lgao            #                                               "Mi segunda secuencia 2"
52630fdf1140b8d1ce93f3821d986fa165552023440lgao            #     #string MY_STRING_2     #language eng     "My first English string line 1"
52730fdf1140b8d1ce93f3821d986fa165552023440lgao            #                                               "My first English string line 2"
52830fdf1140b8d1ce93f3821d986fa165552023440lgao            #     #string MY_STRING_2     #language spa     "Mi segunda secuencia 1"
52930fdf1140b8d1ce93f3821d986fa165552023440lgao            #                                               "Mi segunda secuencia 2"
53030fdf1140b8d1ce93f3821d986fa165552023440lgao            #
53130fdf1140b8d1ce93f3821d986fa165552023440lgao            if Line.find(u'#string ') >= 0 and Line.find(u'#language ') >= 0:
53230fdf1140b8d1ce93f3821d986fa165552023440lgao                StringItem = Line
53330fdf1140b8d1ce93f3821d986fa165552023440lgao                for IndexJ in range(IndexI + 1, len(Lines)):
53430fdf1140b8d1ce93f3821d986fa165552023440lgao                    if Lines[IndexJ].find(u'#string ') >= 0 and Lines[IndexJ].find(u'#language ') >= 0:
53530fdf1140b8d1ce93f3821d986fa165552023440lgao                        IndexI = IndexJ
53630fdf1140b8d1ce93f3821d986fa165552023440lgao                        break
53730fdf1140b8d1ce93f3821d986fa165552023440lgao                    elif Lines[IndexJ].find(u'#string ') < 0 and Lines[IndexJ].find(u'#language ') >= 0:
53830fdf1140b8d1ce93f3821d986fa165552023440lgao                        StringItem = StringItem + Lines[IndexJ]
53930fdf1140b8d1ce93f3821d986fa165552023440lgao                    elif Lines[IndexJ].count(u'\"') >= 2:
54030fdf1140b8d1ce93f3821d986fa165552023440lgao                        StringItem = StringItem[ : StringItem.rfind(u'\"')] + Lines[IndexJ][Lines[IndexJ].find(u'\"') + len(u'\"') : ]
54130fdf1140b8d1ce93f3821d986fa165552023440lgao                self.GetStringObject(StringItem)
54230fdf1140b8d1ce93f3821d986fa165552023440lgao                continue
54330fdf1140b8d1ce93f3821d986fa165552023440lgao
54430fdf1140b8d1ce93f3821d986fa165552023440lgao    #
54530fdf1140b8d1ce93f3821d986fa165552023440lgao    # Load multiple .uni files
54630fdf1140b8d1ce93f3821d986fa165552023440lgao    #
54752302d4dee589a5df43a464420c9fe68ba83937dlgao    def LoadUniFiles(self, FileList):
54830fdf1140b8d1ce93f3821d986fa165552023440lgao        if len(FileList) > 0:
54952302d4dee589a5df43a464420c9fe68ba83937dlgao            for File in FileList:
55052302d4dee589a5df43a464420c9fe68ba83937dlgao                self.LoadUniFile(File)
55130fdf1140b8d1ce93f3821d986fa165552023440lgao
55230fdf1140b8d1ce93f3821d986fa165552023440lgao    #
55330fdf1140b8d1ce93f3821d986fa165552023440lgao    # Add a string to list
55430fdf1140b8d1ce93f3821d986fa165552023440lgao    #
55530fdf1140b8d1ce93f3821d986fa165552023440lgao    def AddStringToList(self, Name, Language, Value, Token = None, Referenced = False, UseOtherLangDef = '', Index = -1):
55608dd311f5dc735c595d39faf2e6f7e2810bb79a9lgao        for LangNameItem in self.LanguageDef:
55708dd311f5dc735c595d39faf2e6f7e2810bb79a9lgao            if Language == LangNameItem[0]:
55808dd311f5dc735c595d39faf2e6f7e2810bb79a9lgao                break
55908dd311f5dc735c595d39faf2e6f7e2810bb79a9lgao        else:
56008dd311f5dc735c595d39faf2e6f7e2810bb79a9lgao            EdkLogger.error('Unicode File Parser', FORMAT_NOT_SUPPORTED, "The language '%s' for %s is not defined in Unicode file %s." \
56108dd311f5dc735c595d39faf2e6f7e2810bb79a9lgao                            % (Language, Name, self.File))
56208dd311f5dc735c595d39faf2e6f7e2810bb79a9lgao
56330fdf1140b8d1ce93f3821d986fa165552023440lgao        if Language not in self.OrderedStringList:
56430fdf1140b8d1ce93f3821d986fa165552023440lgao            self.OrderedStringList[Language] = []
56579b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao            self.OrderedStringDict[Language] = {}
56630fdf1140b8d1ce93f3821d986fa165552023440lgao
567756ad8f8e9d3e345f1883546e2a3125203e234aalgao        IsAdded = True
56879b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao        if Name in self.OrderedStringDict[Language]:
56979b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao            IsAdded = False
57079b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao            if Value != None:
57179b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao                ItemIndexInList = self.OrderedStringDict[Language][Name]
57279b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao                Item = self.OrderedStringList[Language][ItemIndexInList]
57379b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao                Item.UpdateValue(Value)
57447fea6afd74af76c7e2a2b03d319b7ac035ac26aYonghong Zhu                Item.UseOtherLangDef = ''
575756ad8f8e9d3e345f1883546e2a3125203e234aalgao
576756ad8f8e9d3e345f1883546e2a3125203e234aalgao        if IsAdded:
57730fdf1140b8d1ce93f3821d986fa165552023440lgao            Token = len(self.OrderedStringList[Language])
57830fdf1140b8d1ce93f3821d986fa165552023440lgao            if Index == -1:
57930fdf1140b8d1ce93f3821d986fa165552023440lgao                self.OrderedStringList[Language].append(StringDefClassObject(Name, Value, Referenced, Token, UseOtherLangDef))
58079b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao                self.OrderedStringDict[Language][Name] = Token
581756ad8f8e9d3e345f1883546e2a3125203e234aalgao                for LangName in self.LanguageDef:
582756ad8f8e9d3e345f1883546e2a3125203e234aalgao                    #
583756ad8f8e9d3e345f1883546e2a3125203e234aalgao                    # New STRING token will be added into all language string lists.
584756ad8f8e9d3e345f1883546e2a3125203e234aalgao                    # so that the unique STRING identifier is reserved for all languages in the package list.
585756ad8f8e9d3e345f1883546e2a3125203e234aalgao                    #
586756ad8f8e9d3e345f1883546e2a3125203e234aalgao                    if LangName[0] != Language:
587756ad8f8e9d3e345f1883546e2a3125203e234aalgao                        if UseOtherLangDef != '':
588756ad8f8e9d3e345f1883546e2a3125203e234aalgao                            OtherLangDef = UseOtherLangDef
589756ad8f8e9d3e345f1883546e2a3125203e234aalgao                        else:
590756ad8f8e9d3e345f1883546e2a3125203e234aalgao                            OtherLangDef = Language
591756ad8f8e9d3e345f1883546e2a3125203e234aalgao                        self.OrderedStringList[LangName[0]].append(StringDefClassObject(Name, '', Referenced, Token, OtherLangDef))
59279b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao                        self.OrderedStringDict[LangName[0]][Name] = len(self.OrderedStringList[LangName[0]]) - 1
59330fdf1140b8d1ce93f3821d986fa165552023440lgao            else:
59430fdf1140b8d1ce93f3821d986fa165552023440lgao                self.OrderedStringList[Language].insert(Index, StringDefClassObject(Name, Value, Referenced, Token, UseOtherLangDef))
59579b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao                self.OrderedStringDict[Language][Name] = Index
59630fdf1140b8d1ce93f3821d986fa165552023440lgao
59730fdf1140b8d1ce93f3821d986fa165552023440lgao    #
59830fdf1140b8d1ce93f3821d986fa165552023440lgao    # Set the string as referenced
59930fdf1140b8d1ce93f3821d986fa165552023440lgao    #
60030fdf1140b8d1ce93f3821d986fa165552023440lgao    def SetStringReferenced(self, Name):
601756ad8f8e9d3e345f1883546e2a3125203e234aalgao        #
602756ad8f8e9d3e345f1883546e2a3125203e234aalgao        # String stoken are added in the same order in all language string lists.
603756ad8f8e9d3e345f1883546e2a3125203e234aalgao        # So, only update the status of string stoken in first language string list.
604756ad8f8e9d3e345f1883546e2a3125203e234aalgao        #
605756ad8f8e9d3e345f1883546e2a3125203e234aalgao        Lang = self.LanguageDef[0][0]
60679b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao        if Name in self.OrderedStringDict[Lang]:
60779b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao            ItemIndexInList = self.OrderedStringDict[Lang][Name]
60879b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao            Item = self.OrderedStringList[Lang][ItemIndexInList]
60979b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao            Item.Referenced = True
61079b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao
61130fdf1140b8d1ce93f3821d986fa165552023440lgao    #
61230fdf1140b8d1ce93f3821d986fa165552023440lgao    # Search the string in language definition by Name
61330fdf1140b8d1ce93f3821d986fa165552023440lgao    #
61430fdf1140b8d1ce93f3821d986fa165552023440lgao    def FindStringValue(self, Name, Lang):
61579b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao        if Name in self.OrderedStringDict[Lang]:
61679b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao            ItemIndexInList = self.OrderedStringDict[Lang][Name]
61779b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao            return self.OrderedStringList[Lang][ItemIndexInList]
61830fdf1140b8d1ce93f3821d986fa165552023440lgao
61930fdf1140b8d1ce93f3821d986fa165552023440lgao        return None
62030fdf1140b8d1ce93f3821d986fa165552023440lgao
62130fdf1140b8d1ce93f3821d986fa165552023440lgao    #
62230fdf1140b8d1ce93f3821d986fa165552023440lgao    # Search the string in language definition by Token
62330fdf1140b8d1ce93f3821d986fa165552023440lgao    #
62430fdf1140b8d1ce93f3821d986fa165552023440lgao    def FindByToken(self, Token, Lang):
62530fdf1140b8d1ce93f3821d986fa165552023440lgao        for Item in self.OrderedStringList[Lang]:
62630fdf1140b8d1ce93f3821d986fa165552023440lgao            if Item.Token == Token:
62730fdf1140b8d1ce93f3821d986fa165552023440lgao                return Item
62830fdf1140b8d1ce93f3821d986fa165552023440lgao
62930fdf1140b8d1ce93f3821d986fa165552023440lgao        return None
63030fdf1140b8d1ce93f3821d986fa165552023440lgao
63130fdf1140b8d1ce93f3821d986fa165552023440lgao    #
63230fdf1140b8d1ce93f3821d986fa165552023440lgao    # Re-order strings and re-generate tokens
63330fdf1140b8d1ce93f3821d986fa165552023440lgao    #
63430fdf1140b8d1ce93f3821d986fa165552023440lgao    def ReToken(self):
63530fdf1140b8d1ce93f3821d986fa165552023440lgao        #
636756ad8f8e9d3e345f1883546e2a3125203e234aalgao        # Retoken all language strings according to the status of string stoken in the first language string.
63730fdf1140b8d1ce93f3821d986fa165552023440lgao        #
638756ad8f8e9d3e345f1883546e2a3125203e234aalgao        FirstLangName = self.LanguageDef[0][0]
63952302d4dee589a5df43a464420c9fe68ba83937dlgao
64079b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao        # Convert the OrderedStringList to be OrderedStringListByToken in order to faciliate future search by token
64179b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao        for LangNameItem in self.LanguageDef:
64279b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao            self.OrderedStringListByToken[LangNameItem[0]] = {}
64379b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao
64452302d4dee589a5df43a464420c9fe68ba83937dlgao        #
645756ad8f8e9d3e345f1883546e2a3125203e234aalgao        # Use small token for all referred string stoken.
64652302d4dee589a5df43a464420c9fe68ba83937dlgao        #
647756ad8f8e9d3e345f1883546e2a3125203e234aalgao        RefToken = 0
648756ad8f8e9d3e345f1883546e2a3125203e234aalgao        for Index in range (0, len (self.OrderedStringList[FirstLangName])):
649756ad8f8e9d3e345f1883546e2a3125203e234aalgao            FirstLangItem = self.OrderedStringList[FirstLangName][Index]
650756ad8f8e9d3e345f1883546e2a3125203e234aalgao            if FirstLangItem.Referenced == True:
651756ad8f8e9d3e345f1883546e2a3125203e234aalgao                for LangNameItem in self.LanguageDef:
652756ad8f8e9d3e345f1883546e2a3125203e234aalgao                    LangName = LangNameItem[0]
653756ad8f8e9d3e345f1883546e2a3125203e234aalgao                    OtherLangItem = self.OrderedStringList[LangName][Index]
654756ad8f8e9d3e345f1883546e2a3125203e234aalgao                    OtherLangItem.Referenced = True
655756ad8f8e9d3e345f1883546e2a3125203e234aalgao                    OtherLangItem.Token = RefToken
65679b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao                    self.OrderedStringListByToken[LangName][OtherLangItem.Token] = OtherLangItem
657756ad8f8e9d3e345f1883546e2a3125203e234aalgao                RefToken = RefToken + 1
65830fdf1140b8d1ce93f3821d986fa165552023440lgao
65930fdf1140b8d1ce93f3821d986fa165552023440lgao        #
660756ad8f8e9d3e345f1883546e2a3125203e234aalgao        # Use big token for all unreferred string stoken.
66130fdf1140b8d1ce93f3821d986fa165552023440lgao        #
662756ad8f8e9d3e345f1883546e2a3125203e234aalgao        UnRefToken = 0
663756ad8f8e9d3e345f1883546e2a3125203e234aalgao        for Index in range (0, len (self.OrderedStringList[FirstLangName])):
664756ad8f8e9d3e345f1883546e2a3125203e234aalgao            FirstLangItem = self.OrderedStringList[FirstLangName][Index]
665756ad8f8e9d3e345f1883546e2a3125203e234aalgao            if FirstLangItem.Referenced == False:
666756ad8f8e9d3e345f1883546e2a3125203e234aalgao                for LangNameItem in self.LanguageDef:
667756ad8f8e9d3e345f1883546e2a3125203e234aalgao                    LangName = LangNameItem[0]
668756ad8f8e9d3e345f1883546e2a3125203e234aalgao                    OtherLangItem = self.OrderedStringList[LangName][Index]
669756ad8f8e9d3e345f1883546e2a3125203e234aalgao                    OtherLangItem.Token = RefToken + UnRefToken
67079b74a03e018ecbf03d8d50e6f20301e249c1ba5lgao                    self.OrderedStringListByToken[LangName][OtherLangItem.Token] = OtherLangItem
671756ad8f8e9d3e345f1883546e2a3125203e234aalgao                UnRefToken = UnRefToken + 1
67230fdf1140b8d1ce93f3821d986fa165552023440lgao
67330fdf1140b8d1ce93f3821d986fa165552023440lgao    #
67430fdf1140b8d1ce93f3821d986fa165552023440lgao    # Show the instance itself
67530fdf1140b8d1ce93f3821d986fa165552023440lgao    #
67630fdf1140b8d1ce93f3821d986fa165552023440lgao    def ShowMe(self):
67730fdf1140b8d1ce93f3821d986fa165552023440lgao        print self.LanguageDef
67830fdf1140b8d1ce93f3821d986fa165552023440lgao        #print self.OrderedStringList
67930fdf1140b8d1ce93f3821d986fa165552023440lgao        for Item in self.OrderedStringList:
68030fdf1140b8d1ce93f3821d986fa165552023440lgao            print Item
68130fdf1140b8d1ce93f3821d986fa165552023440lgao            for Member in self.OrderedStringList[Item]:
68230fdf1140b8d1ce93f3821d986fa165552023440lgao                print str(Member)
68330fdf1140b8d1ce93f3821d986fa165552023440lgao
68430fdf1140b8d1ce93f3821d986fa165552023440lgao# This acts like the main() function for the script, unless it is 'import'ed into another
68530fdf1140b8d1ce93f3821d986fa165552023440lgao# script.
68630fdf1140b8d1ce93f3821d986fa165552023440lgaoif __name__ == '__main__':
68730fdf1140b8d1ce93f3821d986fa165552023440lgao    EdkLogger.Initialize()
68830fdf1140b8d1ce93f3821d986fa165552023440lgao    EdkLogger.SetLevel(EdkLogger.DEBUG_0)
689da92f27632d2c89fa8726948ac9b02461ca8b61elgao    a = UniFileClassObject([PathClass("C:\\Edk\\Strings.uni"), PathClass("C:\\Edk\\Strings2.uni")])
69030fdf1140b8d1ce93f3821d986fa165552023440lgao    a.ReToken()
69130fdf1140b8d1ce93f3821d986fa165552023440lgao    a.ShowMe()
692