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