]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - BaseTools/Source/Python/UPT/Library/UniClassObject.py
BaseTools: UPT: remove unused variable and inaccessible code.
[mirror_edk2.git] / BaseTools / Source / Python / UPT / Library / UniClassObject.py
... / ...
CommitLineData
1## @file\r
2# Collect all defined strings in multiple uni files.\r
3#\r
4# Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>\r
5#\r
6# This program and the accompanying materials are licensed and made available \r
7# under the terms and conditions of the BSD License which accompanies this \r
8# distribution. The full text of the license may be found at \r
9# http://opensource.org/licenses/bsd-license.php\r
10#\r
11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13#\r
14"""\r
15Collect all defined strings in multiple uni files\r
16"""\r
17\r
18##\r
19# Import Modules\r
20#\r
21import os, codecs, re\r
22import distutils.util\r
23from Logger import ToolError\r
24from Logger import Log as EdkLogger\r
25from Logger import StringTable as ST\r
26from Library.String import GetLineNo\r
27from Library.Misc import PathClass\r
28from Library.Misc import GetCharIndexOutStr\r
29from Library import DataType as DT\r
30from Library.ParserValidate import CheckUTF16FileHeader\r
31\r
32##\r
33# Static definitions\r
34#\r
35UNICODE_WIDE_CHAR = u'\\wide'\r
36UNICODE_NARROW_CHAR = u'\\narrow'\r
37UNICODE_NON_BREAKING_CHAR = u'\\nbr'\r
38UNICODE_UNICODE_CR = '\r'\r
39UNICODE_UNICODE_LF = '\n'\r
40\r
41NARROW_CHAR = u'\uFFF0'\r
42WIDE_CHAR = u'\uFFF1'\r
43NON_BREAKING_CHAR = u'\uFFF2'\r
44CR = u'\u000D'\r
45LF = u'\u000A'\r
46NULL = u'\u0000'\r
47TAB = u'\t'\r
48BACK_SPLASH = u'\\'\r
49\r
50gLANG_CONV_TABLE = {'eng':'en', 'fra':'fr', \\r
51 'aar':'aa', 'abk':'ab', 'ave':'ae', 'afr':'af', 'aka':'ak', 'amh':'am', \\r
52 'arg':'an', 'ara':'ar', 'asm':'as', 'ava':'av', 'aym':'ay', 'aze':'az', \\r
53 'bak':'ba', 'bel':'be', 'bul':'bg', 'bih':'bh', 'bis':'bi', 'bam':'bm', \\r
54 'ben':'bn', 'bod':'bo', 'bre':'br', 'bos':'bs', 'cat':'ca', 'che':'ce', \\r
55 'cha':'ch', 'cos':'co', 'cre':'cr', 'ces':'cs', 'chu':'cu', 'chv':'cv', \\r
56 'cym':'cy', 'dan':'da', 'deu':'de', 'div':'dv', 'dzo':'dz', 'ewe':'ee', \\r
57 'ell':'el', 'epo':'eo', 'spa':'es', 'est':'et', 'eus':'eu', 'fas':'fa', \\r
58 'ful':'ff', 'fin':'fi', 'fij':'fj', 'fao':'fo', 'fry':'fy', 'gle':'ga', \\r
59 'gla':'gd', 'glg':'gl', 'grn':'gn', 'guj':'gu', 'glv':'gv', 'hau':'ha', \\r
60 'heb':'he', 'hin':'hi', 'hmo':'ho', 'hrv':'hr', 'hat':'ht', 'hun':'hu', \\r
61 'hye':'hy', 'her':'hz', 'ina':'ia', 'ind':'id', 'ile':'ie', 'ibo':'ig', \\r
62 'iii':'ii', 'ipk':'ik', 'ido':'io', 'isl':'is', 'ita':'it', 'iku':'iu', \\r
63 'jpn':'ja', 'jav':'jv', 'kat':'ka', 'kon':'kg', 'kik':'ki', 'kua':'kj', \\r
64 'kaz':'kk', 'kal':'kl', 'khm':'km', 'kan':'kn', 'kor':'ko', 'kau':'kr', \\r
65 'kas':'ks', 'kur':'ku', 'kom':'kv', 'cor':'kw', 'kir':'ky', 'lat':'la', \\r
66 'ltz':'lb', 'lug':'lg', 'lim':'li', 'lin':'ln', 'lao':'lo', 'lit':'lt', \\r
67 'lub':'lu', 'lav':'lv', 'mlg':'mg', 'mah':'mh', 'mri':'mi', 'mkd':'mk', \\r
68 'mal':'ml', 'mon':'mn', 'mar':'mr', 'msa':'ms', 'mlt':'mt', 'mya':'my', \\r
69 'nau':'na', 'nob':'nb', 'nde':'nd', 'nep':'ne', 'ndo':'ng', 'nld':'nl', \\r
70 'nno':'nn', 'nor':'no', 'nbl':'nr', 'nav':'nv', 'nya':'ny', 'oci':'oc', \\r
71 'oji':'oj', 'orm':'om', 'ori':'or', 'oss':'os', 'pan':'pa', 'pli':'pi', \\r
72 'pol':'pl', 'pus':'ps', 'por':'pt', 'que':'qu', 'roh':'rm', 'run':'rn', \\r
73 'ron':'ro', 'rus':'ru', 'kin':'rw', 'san':'sa', 'srd':'sc', 'snd':'sd', \\r
74 'sme':'se', 'sag':'sg', 'sin':'si', 'slk':'sk', 'slv':'sl', 'smo':'sm', \\r
75 'sna':'sn', 'som':'so', 'sqi':'sq', 'srp':'sr', 'ssw':'ss', 'sot':'st', \\r
76 'sun':'su', 'swe':'sv', 'swa':'sw', 'tam':'ta', 'tel':'te', 'tgk':'tg', \\r
77 'tha':'th', 'tir':'ti', 'tuk':'tk', 'tgl':'tl', 'tsn':'tn', 'ton':'to', \\r
78 'tur':'tr', 'tso':'ts', 'tat':'tt', 'twi':'tw', 'tah':'ty', 'uig':'ug', \\r
79 'ukr':'uk', 'urd':'ur', 'uzb':'uz', 'ven':'ve', 'vie':'vi', 'vol':'vo', \\r
80 'wln':'wa', 'wol':'wo', 'xho':'xh', 'yid':'yi', 'yor':'yo', 'zha':'za', \\r
81 'zho':'zh', 'zul':'zu'}\r
82\r
83## Convert a python unicode string to a normal string\r
84#\r
85# Convert a python unicode string to a normal string\r
86# UniToStr(u'I am a string') is 'I am a string'\r
87#\r
88# @param Uni: The python unicode string\r
89#\r
90# @retval: The formatted normal string\r
91#\r
92def UniToStr(Uni):\r
93 return repr(Uni)[2:-1]\r
94\r
95## Convert a unicode string to a Hex list\r
96#\r
97# Convert a unicode string to a Hex list\r
98# UniToHexList('ABC') is ['0x41', '0x00', '0x42', '0x00', '0x43', '0x00']\r
99#\r
100# @param Uni: The python unicode string\r
101#\r
102# @retval List: The formatted hex list\r
103#\r
104def UniToHexList(Uni):\r
105 List = []\r
106 for Item in Uni:\r
107 Temp = '%04X' % ord(Item)\r
108 List.append('0x' + Temp[2:4])\r
109 List.append('0x' + Temp[0:2])\r
110 return List\r
111\r
112## Convert special unicode characters\r
113#\r
114# Convert special characters to (c), (r) and (tm).\r
115#\r
116# @param Uni: The python unicode string\r
117#\r
118# @retval NewUni: The converted unicode string\r
119#\r
120def ConvertSpecialUnicodes(Uni):\r
121 NewUni = Uni\r
122 NewUni = NewUni.replace(u'\u00A9', '(c)')\r
123 NewUni = NewUni.replace(u'\u00AE', '(r)')\r
124 NewUni = NewUni.replace(u'\u2122', '(tm)')\r
125 return NewUni\r
126\r
127## GetLanguageCode1766\r
128#\r
129# Check the language code read from .UNI file and convert RFC 4646 codes to RFC 1766 codes\r
130# RFC 1766 language codes supported in compatiblity mode\r
131# RFC 4646 language codes supported in native mode\r
132#\r
133# @param LangName: Language codes read from .UNI file\r
134#\r
135# @retval LangName: Valid lanugage code in RFC 1766 format or None\r
136#\r
137def GetLanguageCode1766(LangName, File=None):\r
138 return LangName\r
139\r
140 length = len(LangName)\r
141 if length == 2:\r
142 if LangName.isalpha():\r
143 for Key in gLANG_CONV_TABLE.keys():\r
144 if gLANG_CONV_TABLE.get(Key) == LangName.lower():\r
145 return Key\r
146 elif length == 3:\r
147 if LangName.isalpha() and gLANG_CONV_TABLE.get(LangName.lower()):\r
148 return LangName\r
149 else:\r
150 EdkLogger.Error("Unicode File Parser", \r
151 ToolError.FORMAT_INVALID,\r
152 "Invalid RFC 1766 language code : %s" % LangName, \r
153 File)\r
154 elif length == 5:\r
155 if LangName[0:2].isalpha() and LangName[2] == '-':\r
156 for Key in gLANG_CONV_TABLE.keys():\r
157 if gLANG_CONV_TABLE.get(Key) == LangName[0:2].lower():\r
158 return Key\r
159 elif length >= 6:\r
160 if LangName[0:2].isalpha() and LangName[2] == '-':\r
161 for Key in gLANG_CONV_TABLE.keys():\r
162 if gLANG_CONV_TABLE.get(Key) == LangName[0:2].lower():\r
163 return Key\r
164 if LangName[0:3].isalpha() and gLANG_CONV_TABLE.get(LangName.lower()) == None and LangName[3] == '-':\r
165 for Key in gLANG_CONV_TABLE.keys():\r
166 if Key == LangName[0:3].lower():\r
167 return Key\r
168\r
169 EdkLogger.Error("Unicode File Parser", \r
170 ToolError.FORMAT_INVALID,\r
171 "Invalid RFC 4646 language code : %s" % LangName, \r
172 File)\r
173 \r
174## GetLanguageCode\r
175#\r
176# Check the language code read from .UNI file and convert RFC 1766 codes to RFC 4646 codes if appropriate\r
177# RFC 1766 language codes supported in compatiblity mode\r
178# RFC 4646 language codes supported in native mode\r
179#\r
180# @param LangName: Language codes read from .UNI file\r
181#\r
182# @retval LangName: Valid lanugage code in RFC 4646 format or None\r
183#\r
184def GetLanguageCode(LangName, IsCompatibleMode, File):\r
185 length = len(LangName)\r
186 if IsCompatibleMode:\r
187 if length == 3 and LangName.isalpha():\r
188 TempLangName = gLANG_CONV_TABLE.get(LangName.lower())\r
189 if TempLangName != None:\r
190 return TempLangName\r
191 return LangName\r
192 else:\r
193 EdkLogger.Error("Unicode File Parser", \r
194 ToolError.FORMAT_INVALID,\r
195 "Invalid RFC 1766 language code : %s" % LangName, \r
196 File)\r
197 if (LangName[0] == 'X' or LangName[0] == 'x') and LangName[1] == '-':\r
198 return LangName\r
199 if length == 2:\r
200 if LangName.isalpha():\r
201 return LangName\r
202 elif length == 3:\r
203 if LangName.isalpha() and gLANG_CONV_TABLE.get(LangName.lower()) == None:\r
204 return LangName\r
205 elif length == 5:\r
206 if LangName[0:2].isalpha() and LangName[2] == '-':\r
207 return LangName\r
208 elif length >= 6:\r
209 if LangName[0:2].isalpha() and LangName[2] == '-':\r
210 return LangName\r
211 if LangName[0:3].isalpha() and gLANG_CONV_TABLE.get(LangName.lower()) == None and LangName[3] == '-':\r
212 return LangName\r
213\r
214 EdkLogger.Error("Unicode File Parser", \r
215 ToolError.FORMAT_INVALID,\r
216 "Invalid RFC 4646 language code : %s" % LangName, \r
217 File)\r
218\r
219## FormatUniEntry\r
220#\r
221# Formated the entry in Uni file.\r
222#\r
223# @param StrTokenName StrTokenName.\r
224# @param TokenValueList A list need to be processed.\r
225# @param ContainerFile ContainerFile.\r
226#\r
227# @return formated entry\r
228def FormatUniEntry(StrTokenName, TokenValueList, ContainerFile):\r
229 SubContent = ''\r
230 PreFormatLength = 40\r
231 if len(StrTokenName) > PreFormatLength:\r
232 PreFormatLength = len(StrTokenName) + 1\r
233 for (Lang, Value) in TokenValueList: \r
234 if not Value or Lang == DT.TAB_LANGUAGE_EN_X:\r
235 continue\r
236 if Lang == '':\r
237 Lang = DT.TAB_LANGUAGE_EN_US\r
238 if Lang == 'eng':\r
239 Lang = DT.TAB_LANGUAGE_EN_US\r
240 elif len(Lang.split('-')[0]) == 3:\r
241 Lang = GetLanguageCode(Lang.split('-')[0], True, ContainerFile)\r
242 else:\r
243 Lang = GetLanguageCode(Lang, False, ContainerFile)\r
244 ValueList = Value.split('\n')\r
245 SubValueContent = ''\r
246 for SubValue in ValueList:\r
247 if SubValue.strip():\r
248 SubValueContent += \\r
249 ' ' * (PreFormatLength + len('#language en-US ')) + '\"%s\\n\"' % SubValue.strip() + '\r\n'\r
250 SubValueContent = SubValueContent[(PreFormatLength + len('#language en-US ')):SubValueContent.rfind('\\n')] \\r
251 + '\"' + '\r\n'\r
252 SubContent += ' '*PreFormatLength + '#language %-5s ' % Lang + SubValueContent\r
253 if SubContent:\r
254 SubContent = StrTokenName + ' '*(PreFormatLength - len(StrTokenName)) + SubContent[PreFormatLength:]\r
255 return SubContent\r
256\r
257\r
258## StringDefClassObject\r
259#\r
260# A structure for language definition\r
261#\r
262class StringDefClassObject(object):\r
263 def __init__(self, Name = None, Value = None, Referenced = False, Token = None, UseOtherLangDef = ''):\r
264 self.StringName = ''\r
265 self.StringNameByteList = []\r
266 self.StringValue = ''\r
267 self.StringValueByteList = ''\r
268 self.Token = 0\r
269 self.Referenced = Referenced\r
270 self.UseOtherLangDef = UseOtherLangDef\r
271 self.Length = 0\r
272\r
273 if Name != None:\r
274 self.StringName = Name\r
275 self.StringNameByteList = UniToHexList(Name)\r
276 if Value != None:\r
277 self.StringValue = Value\r
278 self.StringValueByteList = UniToHexList(self.StringValue)\r
279 self.Length = len(self.StringValueByteList)\r
280 if Token != None:\r
281 self.Token = Token\r
282\r
283 def __str__(self):\r
284 return repr(self.StringName) + ' ' + \\r
285 repr(self.Token) + ' ' + \\r
286 repr(self.Referenced) + ' ' + \\r
287 repr(self.StringValue) + ' ' + \\r
288 repr(self.UseOtherLangDef)\r
289\r
290 def UpdateValue(self, Value = None):\r
291 if Value != None:\r
292 if self.StringValue:\r
293 self.StringValue = self.StringValue + '\r\n' + Value\r
294 else:\r
295 self.StringValue = Value\r
296 self.StringValueByteList = UniToHexList(self.StringValue)\r
297 self.Length = len(self.StringValueByteList)\r
298\r
299## UniFileClassObject\r
300#\r
301# A structure for .uni file definition\r
302#\r
303class UniFileClassObject(object):\r
304 def __init__(self, FileList = None, IsCompatibleMode = False, IncludePathList = None):\r
305 self.FileList = FileList\r
306 self.File = None\r
307 self.IncFileList = FileList\r
308 self.UniFileHeader = ''\r
309 self.Token = 2\r
310 self.LanguageDef = [] #[ [u'LanguageIdentifier', u'PrintableName'], ... ]\r
311 self.OrderedStringList = {} #{ u'LanguageIdentifier' : [StringDefClassObject] }\r
312 self.OrderedStringDict = {} #{ u'LanguageIdentifier' : {StringName:(IndexInList)} }\r
313 self.OrderedStringListByToken = {} #{ u'LanguageIdentifier' : {Token: StringDefClassObject} }\r
314 self.IsCompatibleMode = IsCompatibleMode\r
315 if not IncludePathList:\r
316 self.IncludePathList = []\r
317 else:\r
318 self.IncludePathList = IncludePathList\r
319 if len(self.FileList) > 0:\r
320 self.LoadUniFiles(FileList)\r
321\r
322 #\r
323 # Get Language definition\r
324 #\r
325 def GetLangDef(self, File, Line):\r
326 Lang = distutils.util.split_quoted((Line.split(u"//")[0]))\r
327 if len(Lang) != 3:\r
328 try:\r
329 FileIn = codecs.open(File.Path, mode='rb', encoding='utf_8').readlines()\r
330 except UnicodeError, Xstr:\r
331 FileIn = codecs.open(File.Path, mode='rb', encoding='utf_16').readlines()\r
332 except UnicodeError, Xstr:\r
333 FileIn = codecs.open(File.Path, mode='rb', encoding='utf_16_le').readlines()\r
334 except:\r
335 EdkLogger.Error("Unicode File Parser", \r
336 ToolError.FILE_OPEN_FAILURE, \r
337 "File read failure: %s" % str(Xstr),\r
338 ExtraData=File)\r
339 LineNo = GetLineNo(FileIn, Line, False)\r
340 EdkLogger.Error("Unicode File Parser", \r
341 ToolError.PARSER_ERROR,\r
342 "Wrong language definition", \r
343 ExtraData="""%s\n\t*Correct format is like '#langdef en-US "English"'""" % Line, \r
344 File = File, Line = LineNo)\r
345 else:\r
346 LangName = GetLanguageCode(Lang[1], self.IsCompatibleMode, self.File)\r
347 LangPrintName = Lang[2]\r
348\r
349 IsLangInDef = False\r
350 for Item in self.LanguageDef:\r
351 if Item[0] == LangName:\r
352 IsLangInDef = True\r
353 break\r
354\r
355 if not IsLangInDef:\r
356 self.LanguageDef.append([LangName, LangPrintName])\r
357\r
358 #\r
359 # Add language string\r
360 #\r
361 self.AddStringToList(u'$LANGUAGE_NAME', LangName, LangName, 0, True, Index=0)\r
362 self.AddStringToList(u'$PRINTABLE_LANGUAGE_NAME', LangName, LangPrintName, 1, True, Index=1)\r
363\r
364 if not IsLangInDef:\r
365 #\r
366 # The found STRING tokens will be added into new language string list\r
367 # so that the unique STRING identifier is reserved for all languages in the package list. \r
368 #\r
369 FirstLangName = self.LanguageDef[0][0]\r
370 if LangName != FirstLangName:\r
371 for Index in range (2, len (self.OrderedStringList[FirstLangName])):\r
372 Item = self.OrderedStringList[FirstLangName][Index]\r
373 if Item.UseOtherLangDef != '':\r
374 OtherLang = Item.UseOtherLangDef\r
375 else:\r
376 OtherLang = FirstLangName\r
377 self.OrderedStringList[LangName].append (StringDefClassObject(Item.StringName, \r
378 '', \r
379 Item.Referenced, \r
380 Item.Token, \r
381 OtherLang))\r
382 self.OrderedStringDict[LangName][Item.StringName] = len(self.OrderedStringList[LangName]) - 1\r
383 return True\r
384\r
385 #\r
386 # Get String name and value\r
387 #\r
388 def GetStringObject(self, Item):\r
389 Language = ''\r
390 Value = ''\r
391\r
392 Name = Item.split()[1]\r
393 # Check the string name is the upper character\r
394 if Name != '':\r
395 MatchString = re.match('[A-Z0-9_]+', Name, re.UNICODE)\r
396 if MatchString == None or MatchString.end(0) != len(Name):\r
397 EdkLogger.Error("Unicode File Parser", \r
398 ToolError.FORMAT_INVALID,\r
399 'The string token name %s in UNI file %s must be upper case character.' %(Name, self.File))\r
400 LanguageList = Item.split(u'#language ')\r
401 for IndexI in range(len(LanguageList)):\r
402 if IndexI == 0:\r
403 continue\r
404 else:\r
405 Language = LanguageList[IndexI].split()[0]\r
406 #.replace(u'\r\n', u'')\r
407 Value = \\r
408 LanguageList[IndexI][LanguageList[IndexI].find(u'\"') + len(u'\"') : LanguageList[IndexI].rfind(u'\"')] \r
409 Language = GetLanguageCode(Language, self.IsCompatibleMode, self.File)\r
410 self.AddStringToList(Name, Language, Value)\r
411\r
412 #\r
413 # Get include file list and load them\r
414 #\r
415 def GetIncludeFile(self, Item, Dir = None):\r
416 if Dir:\r
417 pass\r
418 FileName = Item[Item.find(u'!include ') + len(u'!include ') :Item.find(u' ', len(u'!include '))][1:-1]\r
419 self.LoadUniFile(FileName)\r
420\r
421 #\r
422 # Pre-process before parse .uni file\r
423 #\r
424 def PreProcess(self, File, IsIncludeFile=False):\r
425 if not os.path.exists(File.Path) or not os.path.isfile(File.Path):\r
426 EdkLogger.Error("Unicode File Parser", \r
427 ToolError.FILE_NOT_FOUND,\r
428 ExtraData=File.Path)\r
429\r
430 #\r
431 # Check file header of the Uni file\r
432 #\r
433# if not CheckUTF16FileHeader(File.Path):\r
434# EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID,\r
435# ExtraData='The file %s is either invalid UTF-16LE or it is missing the BOM.' % File.Path)\r
436\r
437 try:\r
438 FileIn = codecs.open(File.Path, mode='rb', encoding='utf_8').readlines()\r
439 except UnicodeError, Xstr:\r
440 FileIn = codecs.open(File.Path, mode='rb', encoding='utf_16').readlines()\r
441 except UnicodeError:\r
442 FileIn = codecs.open(File.Path, mode='rb', encoding='utf_16_le').readlines()\r
443 except:\r
444 EdkLogger.Error("Unicode File Parser", ToolError.FILE_OPEN_FAILURE, ExtraData=File.Path)\r
445 \r
446 \r
447 #\r
448 # get the file header\r
449 #\r
450 Lines = []\r
451 HeaderStart = False\r
452 HeaderEnd = False\r
453 if not self.UniFileHeader:\r
454 FirstGenHeader = True\r
455 else:\r
456 FirstGenHeader = False\r
457 for Line in FileIn:\r
458 Line = Line.strip()\r
459 if Line == u'':\r
460 continue\r
461 if Line.startswith(DT.TAB_COMMENT_EDK1_SPLIT) and (Line.find(DT.TAB_HEADER_COMMENT) > -1) \\r
462 and not HeaderEnd and not HeaderStart:\r
463 HeaderStart = True\r
464 if not Line.startswith(DT.TAB_COMMENT_EDK1_SPLIT) and HeaderStart and not HeaderEnd:\r
465 HeaderEnd = True\r
466 if Line.startswith(DT.TAB_COMMENT_EDK1_SPLIT) and HeaderStart and not HeaderEnd and FirstGenHeader:\r
467 self.UniFileHeader += Line + '\r\n'\r
468 continue\r
469 \r
470 #\r
471 # Use unique identifier\r
472 #\r
473 FindFlag = -1\r
474 LineCount = 0\r
475 MultiLineFeedExits = False\r
476 #\r
477 # 0: initial value\r
478 # 1: signle String entry exist\r
479 # 2: line feed exist under the some signle String entry\r
480 #\r
481 StringEntryExistsFlag = 0\r
482 for Line in FileIn:\r
483 Line = FileIn[LineCount]\r
484 LineCount += 1\r
485 Line = Line.strip()\r
486 #\r
487 # Ignore comment line and empty line\r
488 # \r
489 if Line == u'' or Line.startswith(u'//'):\r
490 #\r
491 # Change the single line String entry flag status\r
492 #\r
493 if StringEntryExistsFlag == 1:\r
494 StringEntryExistsFlag = 2\r
495 #\r
496 # If the '#string' line and the '#language' line are not in the same line,\r
497 # there should be only one line feed character betwwen them\r
498 #\r
499 if MultiLineFeedExits:\r
500 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
501 continue\r
502\r
503 MultiLineFeedExits = False\r
504 #\r
505 # Process comment embeded in string define lines\r
506 #\r
507 FindFlag = Line.find(u'//')\r
508 if FindFlag != -1 and Line.find(u'//') < Line.find(u'"'):\r
509 Line = Line.replace(Line[FindFlag:], u' ')\r
510 if FileIn[LineCount].strip().startswith('#language'):\r
511 Line = Line + FileIn[LineCount]\r
512 FileIn[LineCount-1] = Line\r
513 FileIn[LineCount] = '\r\n'\r
514 LineCount -= 1\r
515 for Index in xrange (LineCount + 1, len (FileIn) - 1):\r
516 if (Index == len(FileIn) -1):\r
517 FileIn[Index] = '\r\n'\r
518 else:\r
519 FileIn[Index] = FileIn[Index + 1]\r
520 continue\r
521 CommIndex = GetCharIndexOutStr(u'/', Line)\r
522 if CommIndex > -1:\r
523 if (len(Line) - 1) > CommIndex:\r
524 if Line[CommIndex+1] == u'/':\r
525 Line = Line[:CommIndex].strip()\r
526 else:\r
527 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
528 else:\r
529 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
530 \r
531 Line = Line.replace(UNICODE_WIDE_CHAR, WIDE_CHAR)\r
532 Line = Line.replace(UNICODE_NARROW_CHAR, NARROW_CHAR)\r
533 Line = Line.replace(UNICODE_NON_BREAKING_CHAR, NON_BREAKING_CHAR)\r
534\r
535 Line = Line.replace(u'\\\\', u'\u0006')\r
536 Line = Line.replace(u'\\r\\n', CR + LF)\r
537 Line = Line.replace(u'\\n', CR + LF)\r
538 Line = Line.replace(u'\\r', CR)\r
539 Line = Line.replace(u'\\t', u'\t')\r
540 Line = Line.replace(u'''\"''', u'''"''')\r
541 Line = Line.replace(u'\t', u' ')\r
542 Line = Line.replace(u'\u0006', u'\\')\r
543\r
544 #\r
545 # Check if single line has correct '"'\r
546 #\r
547 if Line.startswith(u'#string') and Line.find(u'#language') > -1 and Line.find('"') > Line.find(u'#language'):\r
548 if not Line.endswith('"'):\r
549 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID,\r
550 ExtraData='''The line %s misses '"' at the end of it in file %s'''\r
551 % (LineCount, File.Path))\r
552\r
553 #\r
554 # Between Name entry and Language entry can not contain line feed\r
555 #\r
556 if Line.startswith(u'#string') and Line.find(u'#language') == -1:\r
557 MultiLineFeedExits = True\r
558 \r
559 if Line.startswith(u'#string') and Line.find(u'#language') > 0 and Line.find(u'"') < 0:\r
560 MultiLineFeedExits = True\r
561 \r
562 #\r
563 # Between Language entry and String entry can not contain line feed\r
564 #\r
565 if Line.startswith(u'#language') and len(Line.split()) == 2:\r
566 MultiLineFeedExits = True\r
567 \r
568 #\r
569 # Between two String entry, can not contain line feed\r
570 #\r
571 if Line.startswith(u'"'):\r
572 if StringEntryExistsFlag == 2:\r
573 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID,\r
574 Message=ST.ERR_UNIPARSE_LINEFEED_UP_EXIST % Line, ExtraData=File.Path)\r
575\r
576 StringEntryExistsFlag = 1\r
577 if not Line.endswith('"'):\r
578 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID,\r
579 ExtraData='''The line %s misses '"' at the end of it in file %s'''\r
580 % (LineCount, File.Path))\r
581 elif Line.startswith(u'#language'):\r
582 if StringEntryExistsFlag == 2:\r
583 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID,\r
584 Message=ST.ERR_UNI_MISS_STRING_ENTRY % Line, ExtraData=File.Path)\r
585 StringEntryExistsFlag = 0\r
586 else:\r
587 StringEntryExistsFlag = 0\r
588\r
589 Lines.append(Line)\r
590 \r
591 #\r
592 # Convert string def format as below\r
593 #\r
594 # #string MY_STRING_1\r
595 # #language eng\r
596 # "My first English string line 1"\r
597 # "My first English string line 2"\r
598 # #string MY_STRING_1\r
599 # #language spa\r
600 # "Mi segunda secuencia 1"\r
601 # "Mi segunda secuencia 2"\r
602 #\r
603 \r
604 if not IsIncludeFile and not Lines:\r
605 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
606 Message=ST.ERR_UNIPARSE_NO_SECTION_EXIST, \\r
607 ExtraData=File.Path) \r
608\r
609 NewLines = []\r
610 StrName = u''\r
611 ExistStrNameList = []\r
612 for Line in Lines:\r
613 if StrName and not StrName.split()[1].startswith(DT.TAB_STR_TOKENCNAME + DT.TAB_UNDERLINE_SPLIT):\r
614 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
615 Message=ST.ERR_UNIPARSE_STRNAME_FORMAT_ERROR % StrName.split()[1], \\r
616 ExtraData=File.Path)\r
617 \r
618 if StrName and len(StrName.split()[1].split(DT.TAB_UNDERLINE_SPLIT)) == 4:\r
619 StringTokenList = StrName.split()[1].split(DT.TAB_UNDERLINE_SPLIT)\r
620 if (StringTokenList[3].upper() in [DT.TAB_STR_TOKENPROMPT, DT.TAB_STR_TOKENHELP] and \\r
621 StringTokenList[3] not in [DT.TAB_STR_TOKENPROMPT, DT.TAB_STR_TOKENHELP]) or \\r
622 (StringTokenList[2].upper() == DT.TAB_STR_TOKENERR and StringTokenList[2] != DT.TAB_STR_TOKENERR):\r
623 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
624 Message=ST.ERR_UNIPARSE_STRTOKEN_FORMAT_ERROR % StrName.split()[1], \\r
625 ExtraData=File.Path)\r
626 \r
627 if Line.count(u'#language') > 1:\r
628 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
629 Message=ST.ERR_UNIPARSE_SEP_LANGENTRY_LINE % Line, \\r
630 ExtraData=File.Path) \r
631 \r
632 if Line.startswith(u'//'):\r
633 continue\r
634 elif Line.startswith(u'#langdef'):\r
635 if len(Line.split()) == 2:\r
636 NewLines.append(Line)\r
637 continue\r
638 elif len(Line.split()) > 2 and Line.find(u'"') > 0: \r
639 NewLines.append(Line[:Line.find(u'"')].strip())\r
640 NewLines.append(Line[Line.find(u'"'):])\r
641 else:\r
642 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
643 elif Line.startswith(u'#string'):\r
644 if len(Line.split()) == 2:\r
645 StrName = Line\r
646 if StrName:\r
647 if StrName.split()[1] not in ExistStrNameList:\r
648 ExistStrNameList.append(StrName.split()[1].strip())\r
649 elif StrName.split()[1] in [DT.TAB_INF_ABSTRACT, DT.TAB_INF_DESCRIPTION, \\r
650 DT.TAB_INF_BINARY_ABSTRACT, DT.TAB_INF_BINARY_DESCRIPTION, \\r
651 DT.TAB_DEC_PACKAGE_ABSTRACT, DT.TAB_DEC_PACKAGE_DESCRIPTION, \\r
652 DT.TAB_DEC_BINARY_ABSTRACT, DT.TAB_DEC_BINARY_DESCRIPTION]:\r
653 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
654 Message=ST.ERR_UNIPARSE_MULTI_ENTRY_EXIST % StrName.split()[1], \\r
655 ExtraData=File.Path)\r
656 continue\r
657 elif len(Line.split()) == 4 and Line.find(u'#language') > 0:\r
658 if Line[Line.find(u'#language')-1] != ' ' or \\r
659 Line[Line.find(u'#language')+len(u'#language')] != u' ':\r
660 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
661 \r
662 if Line.find(u'"') > 0:\r
663 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
664 \r
665 StrName = Line.split()[0] + u' ' + Line.split()[1]\r
666 if StrName:\r
667 if StrName.split()[1] not in ExistStrNameList:\r
668 ExistStrNameList.append(StrName.split()[1].strip())\r
669 elif StrName.split()[1] in [DT.TAB_INF_ABSTRACT, DT.TAB_INF_DESCRIPTION, \\r
670 DT.TAB_INF_BINARY_ABSTRACT, DT.TAB_INF_BINARY_DESCRIPTION, \\r
671 DT.TAB_DEC_PACKAGE_ABSTRACT, DT.TAB_DEC_PACKAGE_DESCRIPTION, \\r
672 DT.TAB_DEC_BINARY_ABSTRACT, DT.TAB_DEC_BINARY_DESCRIPTION]:\r
673 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
674 Message=ST.ERR_UNIPARSE_MULTI_ENTRY_EXIST % StrName.split()[1], \\r
675 ExtraData=File.Path)\r
676 if IsIncludeFile:\r
677 if StrName not in NewLines:\r
678 NewLines.append((Line[:Line.find(u'#language')]).strip())\r
679 else:\r
680 NewLines.append((Line[:Line.find(u'#language')]).strip())\r
681 NewLines.append((Line[Line.find(u'#language'):]).strip())\r
682 elif len(Line.split()) > 4 and Line.find(u'#language') > 0 and Line.find(u'"') > 0:\r
683 if Line[Line.find(u'#language')-1] != u' ' or \\r
684 Line[Line.find(u'#language')+len(u'#language')] != u' ':\r
685 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
686 \r
687 if Line[Line.find(u'"')-1] != u' ':\r
688 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path) \r
689 \r
690 StrName = Line.split()[0] + u' ' + Line.split()[1] \r
691 if StrName:\r
692 if StrName.split()[1] not in ExistStrNameList:\r
693 ExistStrNameList.append(StrName.split()[1].strip())\r
694 elif StrName.split()[1] in [DT.TAB_INF_ABSTRACT, DT.TAB_INF_DESCRIPTION, \\r
695 DT.TAB_INF_BINARY_ABSTRACT, DT.TAB_INF_BINARY_DESCRIPTION, \\r
696 DT.TAB_DEC_PACKAGE_ABSTRACT, DT.TAB_DEC_PACKAGE_DESCRIPTION, \\r
697 DT.TAB_DEC_BINARY_ABSTRACT, DT.TAB_DEC_BINARY_DESCRIPTION]:\r
698 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
699 Message=ST.ERR_UNIPARSE_MULTI_ENTRY_EXIST % StrName.split()[1], \\r
700 ExtraData=File.Path) \r
701 if IsIncludeFile:\r
702 if StrName not in NewLines:\r
703 NewLines.append((Line[:Line.find(u'#language')]).strip())\r
704 else: \r
705 NewLines.append((Line[:Line.find(u'#language')]).strip())\r
706 NewLines.append((Line[Line.find(u'#language'):Line.find(u'"')]).strip())\r
707 NewLines.append((Line[Line.find(u'"'):]).strip())\r
708 else:\r
709 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
710 elif Line.startswith(u'#language'):\r
711 if len(Line.split()) == 2:\r
712 if IsIncludeFile:\r
713 if StrName not in NewLines:\r
714 NewLines.append(StrName)\r
715 else:\r
716 NewLines.append(StrName)\r
717 NewLines.append(Line)\r
718 elif len(Line.split()) > 2 and Line.find(u'"') > 0:\r
719 if IsIncludeFile:\r
720 if StrName not in NewLines:\r
721 NewLines.append(StrName)\r
722 else:\r
723 NewLines.append(StrName)\r
724 NewLines.append((Line[:Line.find(u'"')]).strip())\r
725 NewLines.append((Line[Line.find(u'"'):]).strip())\r
726 else:\r
727 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
728 elif Line.startswith(u'"'):\r
729 if u'#string' in Line or u'#language' in Line:\r
730 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
731 NewLines.append(Line)\r
732 else:\r
733 print Line\r
734 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
735 \r
736 if StrName and not StrName.split()[1].startswith(u'STR_'):\r
737 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
738 Message=ST.ERR_UNIPARSE_STRNAME_FORMAT_ERROR % StrName.split()[1], \\r
739 ExtraData=File.Path) \r
740 \r
741 if StrName and not NewLines:\r
742 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
743 Message=ST.ERR_UNI_MISS_LANGENTRY % StrName, \\r
744 ExtraData=File.Path)\r
745 \r
746 #\r
747 # Check Abstract, Description, BinaryAbstract and BinaryDescription order,\r
748 # should be Abstract, Description, BinaryAbstract, BinaryDesctiption\r
749 AbstractPosition = -1\r
750 DescriptionPosition = -1\r
751 BinaryAbstractPosition = -1\r
752 BinaryDescriptionPosition = -1\r
753 for StrName in ExistStrNameList:\r
754 if DT.TAB_HEADER_ABSTRACT.upper() in StrName:\r
755 if 'BINARY' in StrName:\r
756 BinaryAbstractPosition = ExistStrNameList.index(StrName)\r
757 else:\r
758 AbstractPosition = ExistStrNameList.index(StrName)\r
759 if DT.TAB_HEADER_DESCRIPTION.upper() in StrName:\r
760 if 'BINARY' in StrName:\r
761 BinaryDescriptionPosition = ExistStrNameList.index(StrName)\r
762 else:\r
763 DescriptionPosition = ExistStrNameList.index(StrName)\r
764 \r
765 OrderList = sorted([AbstractPosition, DescriptionPosition])\r
766 BinaryOrderList = sorted([BinaryAbstractPosition, BinaryDescriptionPosition])\r
767 Min = OrderList[0]\r
768 Max = OrderList[1]\r
769 BinaryMin = BinaryOrderList[0]\r
770 BinaryMax = BinaryOrderList[1]\r
771 if BinaryDescriptionPosition > -1:\r
772 if not(BinaryDescriptionPosition == BinaryMax and BinaryAbstractPosition == BinaryMin and \\r
773 BinaryMax > Max):\r
774 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
775 Message=ST.ERR_UNIPARSE_ENTRY_ORDER_WRONG, \\r
776 ExtraData=File.Path) \r
777 elif BinaryAbstractPosition > -1:\r
778 if not(BinaryAbstractPosition > Max):\r
779 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
780 Message=ST.ERR_UNIPARSE_ENTRY_ORDER_WRONG, \\r
781 ExtraData=File.Path) \r
782 \r
783 if DescriptionPosition > -1:\r
784 if not(DescriptionPosition == Max and AbstractPosition == Min and \\r
785 DescriptionPosition > AbstractPosition):\r
786 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
787 Message=ST.ERR_UNIPARSE_ENTRY_ORDER_WRONG, \\r
788 ExtraData=File.Path) \r
789 \r
790 if not self.UniFileHeader:\r
791 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \r
792 Message = ST.ERR_NO_SOURCE_HEADER,\r
793 ExtraData=File.Path)\r
794 \r
795 return NewLines\r
796\r
797 #\r
798 # Load a .uni file\r
799 #\r
800 def LoadUniFile(self, File = None):\r
801 if File == None:\r
802 EdkLogger.Error("Unicode File Parser", \r
803 ToolError.PARSER_ERROR, \r
804 Message='No unicode file is given', \r
805 ExtraData=File.Path)\r
806 \r
807 self.File = File\r
808 \r
809 #\r
810 # Process special char in file\r
811 #\r
812 Lines = self.PreProcess(File)\r
813\r
814 #\r
815 # Get Unicode Information\r
816 #\r
817 for IndexI in range(len(Lines)):\r
818 Line = Lines[IndexI]\r
819 if (IndexI + 1) < len(Lines):\r
820 SecondLine = Lines[IndexI + 1]\r
821 if (IndexI + 2) < len(Lines):\r
822 ThirdLine = Lines[IndexI + 2]\r
823\r
824 #\r
825 # Get Language def information\r
826 #\r
827 if Line.find(u'#langdef ') >= 0:\r
828 self.GetLangDef(File, Line + u' ' + SecondLine)\r
829 continue\r
830\r
831 Name = ''\r
832 Language = ''\r
833 Value = ''\r
834 CombineToken = False\r
835 #\r
836 # Get string def information format as below\r
837 #\r
838 # #string MY_STRING_1\r
839 # #language eng\r
840 # "My first English string line 1"\r
841 # "My first English string line 2"\r
842 # #string MY_STRING_1\r
843 # #language spa\r
844 # "Mi segunda secuencia 1"\r
845 # "Mi segunda secuencia 2"\r
846 #\r
847 if Line.find(u'#string ') >= 0 and Line.find(u'#language ') < 0 and \\r
848 SecondLine.find(u'#string ') < 0 and SecondLine.find(u'#language ') >= 0 and \\r
849 ThirdLine.find(u'#string ') < 0 and ThirdLine.find(u'#language ') < 0:\r
850 if Line.find('"') > 0 or SecondLine.find('"') > 0:\r
851 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \r
852 Message=ST.ERR_UNIPARSE_DBLQUOTE_UNMATCHED,\r
853 ExtraData=File.Path)\r
854 \r
855 Name = Line[Line.find(u'#string ') + len(u'#string ') : ].strip(' ')\r
856 Language = SecondLine[SecondLine.find(u'#language ') + len(u'#language ') : ].strip(' ')\r
857 for IndexJ in range(IndexI + 2, len(Lines)):\r
858 if Lines[IndexJ].find(u'#string ') < 0 and Lines[IndexJ].find(u'#language ') < 0 and \\r
859 Lines[IndexJ].strip().startswith(u'"') and Lines[IndexJ].strip().endswith(u'"'):\r
860 if Lines[IndexJ][-2] == ' ':\r
861 CombineToken = True\r
862 if CombineToken:\r
863 if Lines[IndexJ].strip()[1:-1].strip():\r
864 Value = Value + Lines[IndexJ].strip()[1:-1].rstrip() + ' '\r
865 else:\r
866 Value = Value + Lines[IndexJ].strip()[1:-1]\r
867 CombineToken = False\r
868 else:\r
869 Value = Value + Lines[IndexJ].strip()[1:-1] + '\r\n'\r
870 else:\r
871 IndexI = IndexJ\r
872 break\r
873 if Value.endswith('\r\n'):\r
874 Value = Value[: Value.rfind('\r\n')]\r
875 Language = GetLanguageCode(Language, self.IsCompatibleMode, self.File)\r
876 self.AddStringToList(Name, Language, Value)\r
877 continue\r
878\r
879 #\r
880 # Load multiple .uni files\r
881 #\r
882 def LoadUniFiles(self, FileList):\r
883 if len(FileList) > 0:\r
884 for File in FileList:\r
885 FilePath = File.Path.strip()\r
886 if FilePath.endswith('.uni') or FilePath.endswith('.UNI') or FilePath.endswith('.Uni'):\r
887 self.LoadUniFile(File)\r
888\r
889 #\r
890 # Add a string to list\r
891 #\r
892 def AddStringToList(self, Name, Language, Value, Token = 0, Referenced = False, UseOtherLangDef = '', Index = -1):\r
893 for LangNameItem in self.LanguageDef:\r
894 if Language == LangNameItem[0]:\r
895 break\r
896 \r
897 if Language not in self.OrderedStringList:\r
898 self.OrderedStringList[Language] = []\r
899 self.OrderedStringDict[Language] = {}\r
900 \r
901 IsAdded = True\r
902 if Name in self.OrderedStringDict[Language]:\r
903 IsAdded = False\r
904 if Value != None:\r
905 ItemIndexInList = self.OrderedStringDict[Language][Name]\r
906 Item = self.OrderedStringList[Language][ItemIndexInList]\r
907 Item.UpdateValue(Value)\r
908 Item.UseOtherLangDef = '' \r
909\r
910 if IsAdded:\r
911 Token = len(self.OrderedStringList[Language])\r
912 if Index == -1:\r
913 self.OrderedStringList[Language].append(StringDefClassObject(Name, \r
914 Value, \r
915 Referenced, \r
916 Token, \r
917 UseOtherLangDef))\r
918 self.OrderedStringDict[Language][Name] = Token\r
919 for LangName in self.LanguageDef:\r
920 #\r
921 # New STRING token will be added into all language string lists.\r
922 # so that the unique STRING identifier is reserved for all languages in the package list. \r
923 #\r
924 if LangName[0] != Language:\r
925 if UseOtherLangDef != '':\r
926 OtherLangDef = UseOtherLangDef\r
927 else:\r
928 OtherLangDef = Language\r
929 self.OrderedStringList[LangName[0]].append(StringDefClassObject(Name, \r
930 '', \r
931 Referenced, \r
932 Token, \r
933 OtherLangDef))\r
934 self.OrderedStringDict[LangName[0]][Name] = len(self.OrderedStringList[LangName[0]]) - 1\r
935 else:\r
936 self.OrderedStringList[Language].insert(Index, StringDefClassObject(Name, \r
937 Value, \r
938 Referenced, \r
939 Token, \r
940 UseOtherLangDef))\r
941 self.OrderedStringDict[Language][Name] = Index\r
942\r
943 #\r
944 # Set the string as referenced\r
945 #\r
946 def SetStringReferenced(self, Name):\r
947 #\r
948 # String stoken are added in the same order in all language string lists.\r
949 # So, only update the status of string stoken in first language string list.\r
950 #\r
951 Lang = self.LanguageDef[0][0]\r
952 if Name in self.OrderedStringDict[Lang]:\r
953 ItemIndexInList = self.OrderedStringDict[Lang][Name]\r
954 Item = self.OrderedStringList[Lang][ItemIndexInList]\r
955 Item.Referenced = True\r
956\r
957 #\r
958 # Search the string in language definition by Name\r
959 #\r
960 def FindStringValue(self, Name, Lang):\r
961 if Name in self.OrderedStringDict[Lang]:\r
962 ItemIndexInList = self.OrderedStringDict[Lang][Name]\r
963 return self.OrderedStringList[Lang][ItemIndexInList]\r
964\r
965 return None\r
966\r
967 #\r
968 # Search the string in language definition by Token\r
969 #\r
970 def FindByToken(self, Token, Lang):\r
971 for Item in self.OrderedStringList[Lang]:\r
972 if Item.Token == Token:\r
973 return Item\r
974\r
975 return None\r
976\r
977 #\r
978 # Re-order strings and re-generate tokens\r
979 #\r
980 def ReToken(self):\r
981 if len(self.LanguageDef) == 0:\r
982 return None\r
983 #\r
984 # Retoken all language strings according to the status of string stoken in the first language string.\r
985 #\r
986 FirstLangName = self.LanguageDef[0][0]\r
987\r
988 # Convert the OrderedStringList to be OrderedStringListByToken in order to faciliate future search by token\r
989 for LangNameItem in self.LanguageDef:\r
990 self.OrderedStringListByToken[LangNameItem[0]] = {}\r
991\r
992 #\r
993 # Use small token for all referred string stoken.\r
994 #\r
995 RefToken = 0\r
996 for Index in range (0, len (self.OrderedStringList[FirstLangName])):\r
997 FirstLangItem = self.OrderedStringList[FirstLangName][Index]\r
998 if FirstLangItem.Referenced == True:\r
999 for LangNameItem in self.LanguageDef:\r
1000 LangName = LangNameItem[0]\r
1001 OtherLangItem = self.OrderedStringList[LangName][Index]\r
1002 OtherLangItem.Referenced = True\r
1003 OtherLangItem.Token = RefToken\r
1004 self.OrderedStringListByToken[LangName][OtherLangItem.Token] = OtherLangItem\r
1005 RefToken = RefToken + 1\r
1006\r
1007 #\r
1008 # Use big token for all unreferred string stoken.\r
1009 #\r
1010 UnRefToken = 0\r
1011 for Index in range (0, len (self.OrderedStringList[FirstLangName])):\r
1012 FirstLangItem = self.OrderedStringList[FirstLangName][Index]\r
1013 if FirstLangItem.Referenced == False:\r
1014 for LangNameItem in self.LanguageDef:\r
1015 LangName = LangNameItem[0]\r
1016 OtherLangItem = self.OrderedStringList[LangName][Index]\r
1017 OtherLangItem.Token = RefToken + UnRefToken\r
1018 self.OrderedStringListByToken[LangName][OtherLangItem.Token] = OtherLangItem\r
1019 UnRefToken = UnRefToken + 1\r
1020\r
1021 #\r
1022 # Show the instance itself\r
1023 #\r
1024 def ShowMe(self):\r
1025 print self.LanguageDef\r
1026 #print self.OrderedStringList\r
1027 for Item in self.OrderedStringList:\r
1028 print Item\r
1029 for Member in self.OrderedStringList[Item]:\r
1030 print str(Member)\r
1031 \r
1032 #\r
1033 # Read content from '!include' UNI file \r
1034 #\r
1035 def ReadIncludeUNIfile(self, FilaPath):\r
1036 if self.File:\r
1037 pass\r
1038 \r
1039 if not os.path.exists(FilaPath) or not os.path.isfile(FilaPath):\r
1040 EdkLogger.Error("Unicode File Parser", \r
1041 ToolError.FILE_NOT_FOUND,\r
1042 ExtraData=FilaPath)\r
1043 try:\r
1044 FileIn = codecs.open(FilaPath, mode='rb', encoding='utf_8').readlines()\r
1045 except UnicodeError, Xstr:\r
1046 FileIn = codecs.open(FilaPath, mode='rb', encoding='utf_16').readlines()\r
1047 except UnicodeError:\r
1048 FileIn = codecs.open(FilaPath, mode='rb', encoding='utf_16_le').readlines()\r
1049 except:\r
1050 EdkLogger.Error("Unicode File Parser", ToolError.FILE_OPEN_FAILURE, ExtraData=FilaPath)\r
1051 return FileIn\r
1052\r