]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/UPT/Library/UniClassObject.py
BaseTools/UPT: Replace os.linesep with '\r\n' when generating UNI files.
[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
4# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
5#\r
6# This program and the accompanying materials are licensed and made available \r
7# under the terms and conditions of the BSD License which accompanies this \r
8# distribution. The full text of the license may be found at \r
9# http://opensource.org/licenses/bsd-license.php\r
10#\r
11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13#\r
14"""\r
15Collect all defined strings in multiple uni files\r
16"""\r
17\r
18##\r
19# Import Modules\r
20#\r
21import os, codecs, re\r
22import distutils.util\r
23from Logger import ToolError\r
24from Logger import Log as EdkLogger\r
25from Logger import StringTable as ST\r
26from Library.String import GetLineNo\r
27from Library.Misc import PathClass\r
28from Library.Misc import GetCharIndexOutStr\r
29from Library import DataType as DT\r
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
532 IncList = gINCLUDE_PATTERN.findall(Line)\r
533 if len(IncList) == 1:\r
534 for Dir in [File.Dir] + self.IncludePathList:\r
535 IncFile = PathClass(str(IncList[0]), Dir)\r
536 self.IncFileList.append(IncFile)\r
537 if os.path.isfile(IncFile.Path):\r
538 Lines.extend(self.PreProcess(IncFile, True))\r
539 break\r
540 else:\r
541 EdkLogger.Error("Unicode File Parser", \r
542 ToolError.FILE_NOT_FOUND, \r
543 Message="Cannot find include file", \r
544 ExtraData=str(IncList[0]))\r
545 continue\r
546 \r
547 #\r
548 # Between Name entry and Language entry can not contain line feed\r
549 #\r
550 if Line.startswith(u'#string') and Line.find(u'#language') == -1:\r
551 MultiLineFeedExits = True\r
552 \r
553 if Line.startswith(u'#string') and Line.find(u'#language') > 0 and Line.find(u'"') < 0:\r
554 MultiLineFeedExits = True\r
555 \r
556 #\r
557 # Between Language entry and String entry can not contain line feed\r
558 #\r
559 if Line.startswith(u'#language') and len(Line.split()) == 2:\r
560 MultiLineFeedExits = True\r
561 \r
562 #\r
563 # Between two String entry, can not contain line feed\r
564 #\r
565 if Line.startswith(u'"'):\r
566 if StringEntryExistsFlag == 2:\r
567 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \r
568 Message=ST.ERR_UNIPARSE_LINEFEED_UP_EXIST % Line, ExtraData=File.Path)\r
569 \r
570 StringEntryExistsFlag = 1\r
571 if not Line.endswith('"'):\r
572 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
573 elif Line.startswith(u'#language'):\r
574 if StringEntryExistsFlag == 2:\r
575 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \r
576 Message=ST.ERR_UNIPARSE_LINEFEED_UP_EXIST % Line, ExtraData=File.Path)\r
577 StringEntryExistsFlag = 0\r
578 else:\r
579 StringEntryExistsFlag = 0\r
580\r
581 Lines.append(Line)\r
582 \r
583 #\r
584 # Convert string def format as below\r
585 #\r
586 # #string MY_STRING_1\r
587 # #language eng\r
588 # "My first English string line 1"\r
589 # "My first English string line 2"\r
590 # #string MY_STRING_1\r
591 # #language spa\r
592 # "Mi segunda secuencia 1"\r
593 # "Mi segunda secuencia 2"\r
594 #\r
595 \r
596 if not IsIncludeFile and not Lines:\r
597 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
598 Message=ST.ERR_UNIPARSE_NO_SECTION_EXIST, \\r
599 ExtraData=File.Path) \r
600\r
601 NewLines = []\r
602 StrName = u''\r
603 ExistStrNameList = []\r
604 for Line in Lines:\r
605 if StrName and not StrName.split()[1].startswith(DT.TAB_STR_TOKENCNAME + DT.TAB_UNDERLINE_SPLIT):\r
606 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
607 Message=ST.ERR_UNIPARSE_STRNAME_FORMAT_ERROR % StrName.split()[1], \\r
608 ExtraData=File.Path)\r
609 \r
610 if StrName and len(StrName.split()[1].split(DT.TAB_UNDERLINE_SPLIT)) == 4:\r
611 StringTokenList = StrName.split()[1].split(DT.TAB_UNDERLINE_SPLIT)\r
612 if (StringTokenList[3].upper() in [DT.TAB_STR_TOKENPROMPT, DT.TAB_STR_TOKENHELP] and \\r
613 StringTokenList[3] not in [DT.TAB_STR_TOKENPROMPT, DT.TAB_STR_TOKENHELP]) or \\r
614 (StringTokenList[2].upper() == DT.TAB_STR_TOKENERR and StringTokenList[2] != DT.TAB_STR_TOKENERR):\r
615 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
616 Message=ST.ERR_UNIPARSE_STRTOKEN_FORMAT_ERROR % StrName.split()[1], \\r
617 ExtraData=File.Path)\r
618 \r
619 if Line.count(u'#language') > 1:\r
620 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
621 Message=ST.ERR_UNIPARSE_SEP_LANGENTRY_LINE % Line, \\r
622 ExtraData=File.Path) \r
623 \r
624 if Line.startswith(u'//'):\r
625 continue\r
626 elif Line.startswith(u'#langdef'):\r
627 if len(Line.split()) == 2:\r
628 NewLines.append(Line)\r
629 continue\r
630 elif len(Line.split()) > 2 and Line.find(u'"') > 0: \r
631 NewLines.append(Line[:Line.find(u'"')].strip())\r
632 NewLines.append(Line[Line.find(u'"'):])\r
633 else:\r
634 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
635 elif Line.startswith(u'#string'):\r
636 if len(Line.split()) == 2:\r
637 StrName = Line\r
638 if StrName:\r
639 if StrName.split()[1] not in ExistStrNameList:\r
640 ExistStrNameList.append(StrName.split()[1].strip())\r
641 elif StrName.split()[1] in [DT.TAB_INF_ABSTRACT, DT.TAB_INF_DESCRIPTION, \\r
642 DT.TAB_INF_BINARY_ABSTRACT, DT.TAB_INF_BINARY_DESCRIPTION, \\r
643 DT.TAB_DEC_PACKAGE_ABSTRACT, DT.TAB_DEC_PACKAGE_DESCRIPTION, \\r
644 DT.TAB_DEC_BINARY_ABSTRACT, DT.TAB_DEC_BINARY_DESCRIPTION]:\r
645 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
646 Message=ST.ERR_UNIPARSE_MULTI_ENTRY_EXIST % StrName.split()[1], \\r
647 ExtraData=File.Path)\r
648 continue\r
649 elif len(Line.split()) == 4 and Line.find(u'#language') > 0:\r
650 if Line[Line.find(u'#language')-1] != ' ' or \\r
651 Line[Line.find(u'#language')+len(u'#language')] != u' ':\r
652 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
653 \r
654 if Line.find(u'"') > 0:\r
655 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
656 \r
657 StrName = Line.split()[0] + u' ' + Line.split()[1]\r
658 if StrName:\r
659 if StrName.split()[1] not in ExistStrNameList:\r
660 ExistStrNameList.append(StrName.split()[1].strip())\r
661 elif StrName.split()[1] in [DT.TAB_INF_ABSTRACT, DT.TAB_INF_DESCRIPTION, \\r
662 DT.TAB_INF_BINARY_ABSTRACT, DT.TAB_INF_BINARY_DESCRIPTION, \\r
663 DT.TAB_DEC_PACKAGE_ABSTRACT, DT.TAB_DEC_PACKAGE_DESCRIPTION, \\r
664 DT.TAB_DEC_BINARY_ABSTRACT, DT.TAB_DEC_BINARY_DESCRIPTION]:\r
665 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
666 Message=ST.ERR_UNIPARSE_MULTI_ENTRY_EXIST % StrName.split()[1], \\r
667 ExtraData=File.Path)\r
668 if IsIncludeFile:\r
669 if StrName not in NewLines:\r
670 NewLines.append((Line[:Line.find(u'#language')]).strip())\r
671 else:\r
672 NewLines.append((Line[:Line.find(u'#language')]).strip())\r
673 NewLines.append((Line[Line.find(u'#language'):]).strip())\r
674 elif len(Line.split()) > 4 and Line.find(u'#language') > 0 and Line.find(u'"') > 0:\r
675 if Line[Line.find(u'#language')-1] != u' ' or \\r
676 Line[Line.find(u'#language')+len(u'#language')] != u' ':\r
677 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
678 \r
679 if Line[Line.find(u'"')-1] != u' ':\r
680 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path) \r
681 \r
682 StrName = Line.split()[0] + u' ' + Line.split()[1] \r
683 if StrName:\r
684 if StrName.split()[1] not in ExistStrNameList:\r
685 ExistStrNameList.append(StrName.split()[1].strip())\r
686 elif StrName.split()[1] in [DT.TAB_INF_ABSTRACT, DT.TAB_INF_DESCRIPTION, \\r
687 DT.TAB_INF_BINARY_ABSTRACT, DT.TAB_INF_BINARY_DESCRIPTION, \\r
688 DT.TAB_DEC_PACKAGE_ABSTRACT, DT.TAB_DEC_PACKAGE_DESCRIPTION, \\r
689 DT.TAB_DEC_BINARY_ABSTRACT, DT.TAB_DEC_BINARY_DESCRIPTION]:\r
690 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
691 Message=ST.ERR_UNIPARSE_MULTI_ENTRY_EXIST % StrName.split()[1], \\r
692 ExtraData=File.Path) \r
693 if IsIncludeFile:\r
694 if StrName not in NewLines:\r
695 NewLines.append((Line[:Line.find(u'#language')]).strip())\r
696 else: \r
697 NewLines.append((Line[:Line.find(u'#language')]).strip())\r
698 NewLines.append((Line[Line.find(u'#language'):Line.find(u'"')]).strip())\r
699 NewLines.append((Line[Line.find(u'"'):]).strip())\r
700 else:\r
701 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
702 elif Line.startswith(u'#language'):\r
703 if len(Line.split()) == 2:\r
704 if IsIncludeFile:\r
705 if StrName not in NewLines:\r
706 NewLines.append(StrName)\r
707 else:\r
708 NewLines.append(StrName)\r
709 NewLines.append(Line)\r
710 elif len(Line.split()) > 2 and Line.find(u'"') > 0:\r
711 if IsIncludeFile:\r
712 if StrName not in NewLines:\r
713 NewLines.append(StrName)\r
714 else:\r
715 NewLines.append(StrName)\r
716 NewLines.append((Line[:Line.find(u'"')]).strip())\r
717 NewLines.append((Line[Line.find(u'"'):]).strip())\r
718 else:\r
719 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
720 elif Line.startswith(u'"'):\r
721 if u'#string' in Line or u'#language' in Line:\r
722 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
723 NewLines.append(Line)\r
724 else:\r
725 print Line\r
726 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
727 \r
728 if StrName and not StrName.split()[1].startswith(u'STR_'):\r
729 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
730 Message=ST.ERR_UNIPARSE_STRNAME_FORMAT_ERROR % StrName.split()[1], \\r
731 ExtraData=File.Path) \r
732 \r
733 if StrName and not NewLines:\r
734 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
735 Message=ST.ERR_UNI_MISS_LANGENTRY % StrName, \\r
736 ExtraData=File.Path)\r
737 \r
738 #\r
739 # Check Abstract, Description, BinaryAbstract and BinaryDescription order,\r
740 # should be Abstract, Description, BinaryAbstract, BinaryDesctiption\r
741 AbstractPosition = -1\r
742 DescriptionPosition = -1\r
743 BinaryAbstractPosition = -1\r
744 BinaryDescriptionPosition = -1\r
745 for StrName in ExistStrNameList:\r
746 if DT.TAB_HEADER_ABSTRACT.upper() in StrName:\r
747 if 'BINARY' in StrName:\r
748 BinaryAbstractPosition = ExistStrNameList.index(StrName)\r
749 else:\r
750 AbstractPosition = ExistStrNameList.index(StrName)\r
751 if DT.TAB_HEADER_DESCRIPTION.upper() in StrName:\r
752 if 'BINARY' in StrName:\r
753 BinaryDescriptionPosition = ExistStrNameList.index(StrName)\r
754 else:\r
755 DescriptionPosition = ExistStrNameList.index(StrName)\r
756 \r
757 OrderList = sorted([AbstractPosition, DescriptionPosition])\r
758 BinaryOrderList = sorted([BinaryAbstractPosition, BinaryDescriptionPosition])\r
759 Min = OrderList[0]\r
760 Max = OrderList[1]\r
761 BinaryMin = BinaryOrderList[0]\r
762 BinaryMax = BinaryOrderList[1]\r
763 if BinaryDescriptionPosition > -1:\r
764 if not(BinaryDescriptionPosition == BinaryMax and BinaryAbstractPosition == BinaryMin and \\r
765 BinaryMax > Max):\r
766 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
767 Message=ST.ERR_UNIPARSE_ENTRY_ORDER_WRONG, \\r
768 ExtraData=File.Path) \r
769 elif BinaryAbstractPosition > -1:\r
770 if not(BinaryAbstractPosition > Max):\r
771 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
772 Message=ST.ERR_UNIPARSE_ENTRY_ORDER_WRONG, \\r
773 ExtraData=File.Path) \r
774 \r
775 if DescriptionPosition > -1:\r
776 if not(DescriptionPosition == Max and AbstractPosition == Min and \\r
777 DescriptionPosition > AbstractPosition):\r
778 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
779 Message=ST.ERR_UNIPARSE_ENTRY_ORDER_WRONG, \\r
780 ExtraData=File.Path) \r
781 \r
782 if not self.UniFileHeader:\r
783 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \r
784 Message = ST.ERR_NO_SOURCE_HEADER,\r
785 ExtraData=File.Path)\r
786 \r
787 return NewLines\r
788\r
789 #\r
790 # Load a .uni file\r
791 #\r
792 def LoadUniFile(self, File = None):\r
793 if File == None:\r
794 EdkLogger.Error("Unicode File Parser", \r
795 ToolError.PARSER_ERROR, \r
796 Message='No unicode file is given', \r
797 ExtraData=File.Path)\r
798 \r
799 self.File = File\r
800 \r
801 #\r
802 # Process special char in file\r
803 #\r
804 Lines = self.PreProcess(File)\r
805\r
806 #\r
807 # Get Unicode Information\r
808 #\r
809 for IndexI in range(len(Lines)):\r
810 Line = Lines[IndexI]\r
811 if (IndexI + 1) < len(Lines):\r
812 SecondLine = Lines[IndexI + 1]\r
813 if (IndexI + 2) < len(Lines):\r
814 ThirdLine = Lines[IndexI + 2]\r
815\r
816 #\r
817 # Get Language def information\r
818 #\r
819 if Line.find(u'#langdef ') >= 0:\r
820 self.GetLangDef(File, Line + u' ' + SecondLine)\r
821 continue\r
822\r
823 Name = ''\r
824 Language = ''\r
825 Value = ''\r
826 CombineToken = False\r
827 #\r
828 # Get string def information format as below\r
829 #\r
830 # #string MY_STRING_1\r
831 # #language eng\r
832 # "My first English string line 1"\r
833 # "My first English string line 2"\r
834 # #string MY_STRING_1\r
835 # #language spa\r
836 # "Mi segunda secuencia 1"\r
837 # "Mi segunda secuencia 2"\r
838 #\r
839 if Line.find(u'#string ') >= 0 and Line.find(u'#language ') < 0 and \\r
840 SecondLine.find(u'#string ') < 0 and SecondLine.find(u'#language ') >= 0 and \\r
841 ThirdLine.find(u'#string ') < 0 and ThirdLine.find(u'#language ') < 0:\r
842 if Line.find('"') > 0 or SecondLine.find('"') > 0:\r
843 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \r
844 Message=ST.ERR_UNIPARSE_DBLQUOTE_UNMATCHED,\r
845 ExtraData=File.Path)\r
846 \r
847 Name = Line[Line.find(u'#string ') + len(u'#string ') : ].strip(' ')\r
848 Language = SecondLine[SecondLine.find(u'#language ') + len(u'#language ') : ].strip(' ')\r
849 for IndexJ in range(IndexI + 2, len(Lines)):\r
850 if Lines[IndexJ].find(u'#string ') < 0 and Lines[IndexJ].find(u'#language ') < 0 and \\r
851 Lines[IndexJ].strip().startswith(u'"') and Lines[IndexJ].strip().endswith(u'"'):\r
852 if Lines[IndexJ][-2] == ' ':\r
853 CombineToken = True\r
854 if CombineToken:\r
855 if Lines[IndexJ].strip()[1:-1].strip():\r
856 Value = Value + Lines[IndexJ].strip()[1:-1].rstrip() + ' '\r
857 else:\r
858 Value = Value + Lines[IndexJ].strip()[1:-1]\r
859 CombineToken = False\r
860 else:\r
cf2b2bde 861 Value = Value + Lines[IndexJ].strip()[1:-1] + '\r\n'\r
421ccda3
HC
862 else:\r
863 IndexI = IndexJ\r
864 break\r
cf2b2bde
HC
865 if Value.endswith('\r\n'):\r
866 Value = Value[: Value.rfind('\r\n')]\r
421ccda3
HC
867 Language = GetLanguageCode(Language, self.IsCompatibleMode, self.File)\r
868 self.AddStringToList(Name, Language, Value)\r
869 continue\r
870\r
871 #\r
872 # Load multiple .uni files\r
873 #\r
874 def LoadUniFiles(self, FileList):\r
875 if len(FileList) > 0:\r
876 for File in FileList:\r
877 FilePath = File.Path.strip()\r
878 if FilePath.endswith('.uni') or FilePath.endswith('.UNI') or FilePath.endswith('.Uni'):\r
879 self.LoadUniFile(File)\r
880\r
881 #\r
882 # Add a string to list\r
883 #\r
884 def AddStringToList(self, Name, Language, Value, Token = 0, Referenced = False, UseOtherLangDef = '', Index = -1):\r
885 for LangNameItem in self.LanguageDef:\r
886 if Language == LangNameItem[0]:\r
887 break\r
888 \r
889 if Language not in self.OrderedStringList:\r
890 self.OrderedStringList[Language] = []\r
891 self.OrderedStringDict[Language] = {}\r
892 \r
893 IsAdded = True\r
894 if Name in self.OrderedStringDict[Language]:\r
895 IsAdded = False\r
896 if Value != None:\r
897 ItemIndexInList = self.OrderedStringDict[Language][Name]\r
898 Item = self.OrderedStringList[Language][ItemIndexInList]\r
899 Item.UpdateValue(Value)\r
900 Item.UseOtherLangDef = '' \r
901\r
902 if IsAdded:\r
903 Token = len(self.OrderedStringList[Language])\r
904 if Index == -1:\r
905 self.OrderedStringList[Language].append(StringDefClassObject(Name, \r
906 Value, \r
907 Referenced, \r
908 Token, \r
909 UseOtherLangDef))\r
910 self.OrderedStringDict[Language][Name] = Token\r
911 for LangName in self.LanguageDef:\r
912 #\r
913 # New STRING token will be added into all language string lists.\r
914 # so that the unique STRING identifier is reserved for all languages in the package list. \r
915 #\r
916 if LangName[0] != Language:\r
917 if UseOtherLangDef != '':\r
918 OtherLangDef = UseOtherLangDef\r
919 else:\r
920 OtherLangDef = Language\r
921 self.OrderedStringList[LangName[0]].append(StringDefClassObject(Name, \r
922 '', \r
923 Referenced, \r
924 Token, \r
925 OtherLangDef))\r
926 self.OrderedStringDict[LangName[0]][Name] = len(self.OrderedStringList[LangName[0]]) - 1\r
927 else:\r
928 self.OrderedStringList[Language].insert(Index, StringDefClassObject(Name, \r
929 Value, \r
930 Referenced, \r
931 Token, \r
932 UseOtherLangDef))\r
933 self.OrderedStringDict[Language][Name] = Index\r
934\r
935 #\r
936 # Set the string as referenced\r
937 #\r
938 def SetStringReferenced(self, Name):\r
939 #\r
940 # String stoken are added in the same order in all language string lists.\r
941 # So, only update the status of string stoken in first language string list.\r
942 #\r
943 Lang = self.LanguageDef[0][0]\r
944 if Name in self.OrderedStringDict[Lang]:\r
945 ItemIndexInList = self.OrderedStringDict[Lang][Name]\r
946 Item = self.OrderedStringList[Lang][ItemIndexInList]\r
947 Item.Referenced = True\r
948\r
949 #\r
950 # Search the string in language definition by Name\r
951 #\r
952 def FindStringValue(self, Name, Lang):\r
953 if Name in self.OrderedStringDict[Lang]:\r
954 ItemIndexInList = self.OrderedStringDict[Lang][Name]\r
955 return self.OrderedStringList[Lang][ItemIndexInList]\r
956\r
957 return None\r
958\r
959 #\r
960 # Search the string in language definition by Token\r
961 #\r
962 def FindByToken(self, Token, Lang):\r
963 for Item in self.OrderedStringList[Lang]:\r
964 if Item.Token == Token:\r
965 return Item\r
966\r
967 return None\r
968\r
969 #\r
970 # Re-order strings and re-generate tokens\r
971 #\r
972 def ReToken(self):\r
973 if len(self.LanguageDef) == 0:\r
974 return None\r
975 #\r
976 # Retoken all language strings according to the status of string stoken in the first language string.\r
977 #\r
978 FirstLangName = self.LanguageDef[0][0]\r
979\r
980 # Convert the OrderedStringList to be OrderedStringListByToken in order to faciliate future search by token\r
981 for LangNameItem in self.LanguageDef:\r
982 self.OrderedStringListByToken[LangNameItem[0]] = {}\r
983\r
984 #\r
985 # Use small token for all referred string stoken.\r
986 #\r
987 RefToken = 0\r
988 for Index in range (0, len (self.OrderedStringList[FirstLangName])):\r
989 FirstLangItem = self.OrderedStringList[FirstLangName][Index]\r
990 if FirstLangItem.Referenced == True:\r
991 for LangNameItem in self.LanguageDef:\r
992 LangName = LangNameItem[0]\r
993 OtherLangItem = self.OrderedStringList[LangName][Index]\r
994 OtherLangItem.Referenced = True\r
995 OtherLangItem.Token = RefToken\r
996 self.OrderedStringListByToken[LangName][OtherLangItem.Token] = OtherLangItem\r
997 RefToken = RefToken + 1\r
998\r
999 #\r
1000 # Use big token for all unreferred string stoken.\r
1001 #\r
1002 UnRefToken = 0\r
1003 for Index in range (0, len (self.OrderedStringList[FirstLangName])):\r
1004 FirstLangItem = self.OrderedStringList[FirstLangName][Index]\r
1005 if FirstLangItem.Referenced == False:\r
1006 for LangNameItem in self.LanguageDef:\r
1007 LangName = LangNameItem[0]\r
1008 OtherLangItem = self.OrderedStringList[LangName][Index]\r
1009 OtherLangItem.Token = RefToken + UnRefToken\r
1010 self.OrderedStringListByToken[LangName][OtherLangItem.Token] = OtherLangItem\r
1011 UnRefToken = UnRefToken + 1\r
1012\r
1013 #\r
1014 # Show the instance itself\r
1015 #\r
1016 def ShowMe(self):\r
1017 print self.LanguageDef\r
1018 #print self.OrderedStringList\r
1019 for Item in self.OrderedStringList:\r
1020 print Item\r
1021 for Member in self.OrderedStringList[Item]:\r
1022 print str(Member)\r
1023 \r
1024 #\r
1025 # Read content from '!include' UNI file \r
1026 #\r
1027 def ReadIncludeUNIfile(self, FilaPath):\r
1028 if self.File:\r
1029 pass\r
1030 \r
1031 if not os.path.exists(FilaPath) or not os.path.isfile(FilaPath):\r
1032 EdkLogger.Error("Unicode File Parser", \r
1033 ToolError.FILE_NOT_FOUND,\r
1034 ExtraData=FilaPath)\r
1035 try:\r
1036 FileIn = codecs.open(FilaPath, mode='rb', encoding='utf_16').readlines()\r
1037 except UnicodeError:\r
1038 FileIn = codecs.open(FilaPath, mode='rb', encoding='utf_16_le').readlines()\r
1039 except:\r
1040 EdkLogger.Error("Unicode File Parser", ToolError.FILE_OPEN_FAILURE, ExtraData=FilaPath)\r
1041 return FileIn\r
1042\r