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