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