]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/UPT/Library/UniClassObject.py
BaseTools/UPT: Add a checkpoint for missing '"'
[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
85ea493f 4# Copyright (c) 2014 - 2017, 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
645a5128 331 FileIn = codecs.open(File.Path, mode='rb', encoding='utf_8').readlines()\r
4a21fb3b 332 except UnicodeError, Xstr:\r
645a5128 333 FileIn = codecs.open(File.Path, mode='rb', encoding='utf_16').readlines()\r
421ccda3 334 except UnicodeError, Xstr:\r
645a5128 335 FileIn = codecs.open(File.Path, mode='rb', encoding='utf_16_le').readlines()\r
421ccda3
HC
336 except:\r
337 EdkLogger.Error("Unicode File Parser", \r
338 ToolError.FILE_OPEN_FAILURE, \r
339 "File read failure: %s" % str(Xstr),\r
340 ExtraData=File)\r
341 LineNo = GetLineNo(FileIn, Line, False)\r
342 EdkLogger.Error("Unicode File Parser", \r
343 ToolError.PARSER_ERROR,\r
344 "Wrong language definition", \r
345 ExtraData="""%s\n\t*Correct format is like '#langdef en-US "English"'""" % Line, \r
346 File = File, Line = LineNo)\r
347 else:\r
348 LangName = GetLanguageCode(Lang[1], self.IsCompatibleMode, self.File)\r
349 LangPrintName = Lang[2]\r
350\r
351 IsLangInDef = False\r
352 for Item in self.LanguageDef:\r
353 if Item[0] == LangName:\r
354 IsLangInDef = True\r
355 break\r
356\r
357 if not IsLangInDef:\r
358 self.LanguageDef.append([LangName, LangPrintName])\r
359\r
360 #\r
361 # Add language string\r
362 #\r
363 self.AddStringToList(u'$LANGUAGE_NAME', LangName, LangName, 0, True, Index=0)\r
364 self.AddStringToList(u'$PRINTABLE_LANGUAGE_NAME', LangName, LangPrintName, 1, True, Index=1)\r
365\r
366 if not IsLangInDef:\r
367 #\r
368 # The found STRING tokens will be added into new language string list\r
369 # so that the unique STRING identifier is reserved for all languages in the package list. \r
370 #\r
371 FirstLangName = self.LanguageDef[0][0]\r
372 if LangName != FirstLangName:\r
373 for Index in range (2, len (self.OrderedStringList[FirstLangName])):\r
374 Item = self.OrderedStringList[FirstLangName][Index]\r
375 if Item.UseOtherLangDef != '':\r
376 OtherLang = Item.UseOtherLangDef\r
377 else:\r
378 OtherLang = FirstLangName\r
379 self.OrderedStringList[LangName].append (StringDefClassObject(Item.StringName, \r
380 '', \r
381 Item.Referenced, \r
382 Item.Token, \r
383 OtherLang))\r
384 self.OrderedStringDict[LangName][Item.StringName] = len(self.OrderedStringList[LangName]) - 1\r
385 return True\r
386\r
387 #\r
388 # Get String name and value\r
389 #\r
390 def GetStringObject(self, Item):\r
391 Language = ''\r
392 Value = ''\r
393\r
394 Name = Item.split()[1]\r
395 # Check the string name is the upper character\r
396 if Name != '':\r
397 MatchString = re.match('[A-Z0-9_]+', Name, re.UNICODE)\r
398 if MatchString == None or MatchString.end(0) != len(Name):\r
399 EdkLogger.Error("Unicode File Parser", \r
400 ToolError.FORMAT_INVALID,\r
401 'The string token name %s in UNI file %s must be upper case character.' %(Name, self.File))\r
402 LanguageList = Item.split(u'#language ')\r
403 for IndexI in range(len(LanguageList)):\r
404 if IndexI == 0:\r
405 continue\r
406 else:\r
407 Language = LanguageList[IndexI].split()[0]\r
408 #.replace(u'\r\n', u'')\r
409 Value = \\r
410 LanguageList[IndexI][LanguageList[IndexI].find(u'\"') + len(u'\"') : LanguageList[IndexI].rfind(u'\"')] \r
411 Language = GetLanguageCode(Language, self.IsCompatibleMode, self.File)\r
412 self.AddStringToList(Name, Language, Value)\r
413\r
414 #\r
415 # Get include file list and load them\r
416 #\r
417 def GetIncludeFile(self, Item, Dir = None):\r
418 if Dir:\r
419 pass\r
420 FileName = Item[Item.find(u'!include ') + len(u'!include ') :Item.find(u' ', len(u'!include '))][1:-1]\r
421 self.LoadUniFile(FileName)\r
422\r
423 #\r
424 # Pre-process before parse .uni file\r
425 #\r
426 def PreProcess(self, File, IsIncludeFile=False):\r
427 if not os.path.exists(File.Path) or not os.path.isfile(File.Path):\r
428 EdkLogger.Error("Unicode File Parser", \r
429 ToolError.FILE_NOT_FOUND,\r
430 ExtraData=File.Path)\r
431\r
fe90f483
HC
432 #\r
433 # Check file header of the Uni file\r
434 #\r
4a21fb3b
HC
435# if not CheckUTF16FileHeader(File.Path):\r
436# EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID,\r
437# ExtraData='The file %s is either invalid UTF-16LE or it is missing the BOM.' % File.Path)\r
fe90f483 438\r
421ccda3 439 try:\r
645a5128 440 FileIn = codecs.open(File.Path, mode='rb', encoding='utf_8').readlines()\r
4a21fb3b 441 except UnicodeError, Xstr:\r
421ccda3
HC
442 FileIn = codecs.open(File.Path, mode='rb', encoding='utf_16').readlines()\r
443 except UnicodeError:\r
444 FileIn = codecs.open(File.Path, mode='rb', encoding='utf_16_le').readlines()\r
445 except:\r
446 EdkLogger.Error("Unicode File Parser", ToolError.FILE_OPEN_FAILURE, ExtraData=File.Path)\r
447 \r
448 \r
449 #\r
450 # get the file header\r
451 #\r
452 Lines = []\r
453 HeaderStart = False\r
454 HeaderEnd = False\r
455 if not self.UniFileHeader:\r
456 FirstGenHeader = True\r
457 else:\r
458 FirstGenHeader = False\r
459 for Line in FileIn:\r
460 Line = Line.strip()\r
461 if Line == u'':\r
462 continue\r
463 if Line.startswith(DT.TAB_COMMENT_EDK1_SPLIT) and (Line.find(DT.TAB_HEADER_COMMENT) > -1) \\r
464 and not HeaderEnd and not HeaderStart:\r
465 HeaderStart = True\r
466 if not Line.startswith(DT.TAB_COMMENT_EDK1_SPLIT) and HeaderStart and not HeaderEnd:\r
467 HeaderEnd = True\r
468 if Line.startswith(DT.TAB_COMMENT_EDK1_SPLIT) and HeaderStart and not HeaderEnd and FirstGenHeader:\r
cf2b2bde 469 self.UniFileHeader += Line + '\r\n'\r
421ccda3
HC
470 continue\r
471 \r
472 #\r
473 # Use unique identifier\r
474 #\r
475 FindFlag = -1\r
476 LineCount = 0\r
477 MultiLineFeedExits = False\r
478 #\r
479 # 0: initial value\r
480 # 1: signle String entry exist\r
481 # 2: line feed exist under the some signle String entry\r
482 #\r
483 StringEntryExistsFlag = 0\r
484 for Line in FileIn:\r
485 Line = FileIn[LineCount]\r
486 LineCount += 1\r
487 Line = Line.strip()\r
488 #\r
489 # Ignore comment line and empty line\r
490 # \r
491 if Line == u'' or Line.startswith(u'//'):\r
492 #\r
493 # Change the single line String entry flag status\r
494 #\r
495 if StringEntryExistsFlag == 1:\r
496 StringEntryExistsFlag = 2\r
497 #\r
498 # If the '#string' line and the '#language' line are not in the same line,\r
499 # there should be only one line feed character betwwen them\r
500 #\r
501 if MultiLineFeedExits:\r
502 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
503 continue\r
504\r
505 MultiLineFeedExits = False\r
506 #\r
507 # Process comment embeded in string define lines\r
508 #\r
509 FindFlag = Line.find(u'//')\r
510 if FindFlag != -1 and Line.find(u'//') < Line.find(u'"'):\r
511 Line = Line.replace(Line[FindFlag:], u' ')\r
512 if FileIn[LineCount].strip().startswith('#language'):\r
513 Line = Line + FileIn[LineCount]\r
514 FileIn[LineCount-1] = Line\r
cf2b2bde 515 FileIn[LineCount] = '\r\n'\r
421ccda3
HC
516 LineCount -= 1\r
517 for Index in xrange (LineCount + 1, len (FileIn) - 1):\r
518 if (Index == len(FileIn) -1):\r
cf2b2bde 519 FileIn[Index] = '\r\n'\r
421ccda3
HC
520 else:\r
521 FileIn[Index] = FileIn[Index + 1]\r
522 continue\r
523 CommIndex = GetCharIndexOutStr(u'/', Line)\r
524 if CommIndex > -1:\r
525 if (len(Line) - 1) > CommIndex:\r
526 if Line[CommIndex+1] == u'/':\r
527 Line = Line[:CommIndex].strip()\r
528 else:\r
529 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
530 else:\r
531 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
532 \r
533 Line = Line.replace(UNICODE_WIDE_CHAR, WIDE_CHAR)\r
534 Line = Line.replace(UNICODE_NARROW_CHAR, NARROW_CHAR)\r
535 Line = Line.replace(UNICODE_NON_BREAKING_CHAR, NON_BREAKING_CHAR)\r
536\r
537 Line = Line.replace(u'\\\\', u'\u0006')\r
538 Line = Line.replace(u'\\r\\n', CR + LF)\r
539 Line = Line.replace(u'\\n', CR + LF)\r
540 Line = Line.replace(u'\\r', CR)\r
541 Line = Line.replace(u'\\t', u'\t')\r
542 Line = Line.replace(u'''\"''', u'''"''')\r
543 Line = Line.replace(u'\t', u' ')\r
544 Line = Line.replace(u'\u0006', u'\\')\r
545\r
2549514f
HC
546 # IncList = gINCLUDE_PATTERN.findall(Line)\r
547 IncList = []\r
421ccda3
HC
548 if len(IncList) == 1:\r
549 for Dir in [File.Dir] + self.IncludePathList:\r
550 IncFile = PathClass(str(IncList[0]), Dir)\r
551 self.IncFileList.append(IncFile)\r
552 if os.path.isfile(IncFile.Path):\r
553 Lines.extend(self.PreProcess(IncFile, True))\r
554 break\r
555 else:\r
556 EdkLogger.Error("Unicode File Parser", \r
557 ToolError.FILE_NOT_FOUND, \r
558 Message="Cannot find include file", \r
559 ExtraData=str(IncList[0]))\r
560 continue\r
85ea493f
HC
561\r
562 #\r
563 # Check if single line has correct '"'\r
564 #\r
565 if Line.startswith(u'#string') and Line.find(u'#language') > -1 and Line.find('"') > Line.find(u'#language'):\r
566 if not Line.endswith('"'):\r
567 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID,\r
568 ExtraData='''The line %s misses '"' at the end of it in file %s'''\r
569 % (LineCount, File.Path))\r
570\r
421ccda3
HC
571 #\r
572 # Between Name entry and Language entry can not contain line feed\r
573 #\r
574 if Line.startswith(u'#string') and Line.find(u'#language') == -1:\r
575 MultiLineFeedExits = True\r
576 \r
577 if Line.startswith(u'#string') and Line.find(u'#language') > 0 and Line.find(u'"') < 0:\r
578 MultiLineFeedExits = True\r
579 \r
580 #\r
581 # Between Language entry and String entry can not contain line feed\r
582 #\r
583 if Line.startswith(u'#language') and len(Line.split()) == 2:\r
584 MultiLineFeedExits = True\r
585 \r
586 #\r
587 # Between two String entry, can not contain line feed\r
588 #\r
589 if Line.startswith(u'"'):\r
590 if StringEntryExistsFlag == 2:\r
645a5128 591 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID,\r
421ccda3 592 Message=ST.ERR_UNIPARSE_LINEFEED_UP_EXIST % Line, ExtraData=File.Path)\r
645a5128 593\r
421ccda3
HC
594 StringEntryExistsFlag = 1\r
595 if not Line.endswith('"'):\r
fe90f483
HC
596 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID,\r
597 ExtraData='''The line %s misses '"' at the end of it in file %s'''\r
598 % (LineCount, File.Path))\r
421ccda3
HC
599 elif Line.startswith(u'#language'):\r
600 if StringEntryExistsFlag == 2:\r
645a5128 601 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID,\r
fe90f483 602 Message=ST.ERR_UNI_MISS_STRING_ENTRY % Line, ExtraData=File.Path)\r
421ccda3
HC
603 StringEntryExistsFlag = 0\r
604 else:\r
605 StringEntryExistsFlag = 0\r
606\r
607 Lines.append(Line)\r
608 \r
609 #\r
610 # Convert string def format as below\r
611 #\r
612 # #string MY_STRING_1\r
613 # #language eng\r
614 # "My first English string line 1"\r
615 # "My first English string line 2"\r
616 # #string MY_STRING_1\r
617 # #language spa\r
618 # "Mi segunda secuencia 1"\r
619 # "Mi segunda secuencia 2"\r
620 #\r
621 \r
622 if not IsIncludeFile and not Lines:\r
623 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
624 Message=ST.ERR_UNIPARSE_NO_SECTION_EXIST, \\r
625 ExtraData=File.Path) \r
626\r
627 NewLines = []\r
628 StrName = u''\r
629 ExistStrNameList = []\r
630 for Line in Lines:\r
631 if StrName and not StrName.split()[1].startswith(DT.TAB_STR_TOKENCNAME + DT.TAB_UNDERLINE_SPLIT):\r
632 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
633 Message=ST.ERR_UNIPARSE_STRNAME_FORMAT_ERROR % StrName.split()[1], \\r
634 ExtraData=File.Path)\r
635 \r
636 if StrName and len(StrName.split()[1].split(DT.TAB_UNDERLINE_SPLIT)) == 4:\r
637 StringTokenList = StrName.split()[1].split(DT.TAB_UNDERLINE_SPLIT)\r
638 if (StringTokenList[3].upper() in [DT.TAB_STR_TOKENPROMPT, DT.TAB_STR_TOKENHELP] and \\r
639 StringTokenList[3] not in [DT.TAB_STR_TOKENPROMPT, DT.TAB_STR_TOKENHELP]) or \\r
640 (StringTokenList[2].upper() == DT.TAB_STR_TOKENERR and StringTokenList[2] != DT.TAB_STR_TOKENERR):\r
641 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
642 Message=ST.ERR_UNIPARSE_STRTOKEN_FORMAT_ERROR % StrName.split()[1], \\r
643 ExtraData=File.Path)\r
644 \r
645 if Line.count(u'#language') > 1:\r
646 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
647 Message=ST.ERR_UNIPARSE_SEP_LANGENTRY_LINE % Line, \\r
648 ExtraData=File.Path) \r
649 \r
650 if Line.startswith(u'//'):\r
651 continue\r
652 elif Line.startswith(u'#langdef'):\r
653 if len(Line.split()) == 2:\r
654 NewLines.append(Line)\r
655 continue\r
656 elif len(Line.split()) > 2 and Line.find(u'"') > 0: \r
657 NewLines.append(Line[:Line.find(u'"')].strip())\r
658 NewLines.append(Line[Line.find(u'"'):])\r
659 else:\r
660 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
661 elif Line.startswith(u'#string'):\r
662 if len(Line.split()) == 2:\r
663 StrName = Line\r
664 if StrName:\r
665 if StrName.split()[1] not in ExistStrNameList:\r
666 ExistStrNameList.append(StrName.split()[1].strip())\r
667 elif StrName.split()[1] in [DT.TAB_INF_ABSTRACT, DT.TAB_INF_DESCRIPTION, \\r
668 DT.TAB_INF_BINARY_ABSTRACT, DT.TAB_INF_BINARY_DESCRIPTION, \\r
669 DT.TAB_DEC_PACKAGE_ABSTRACT, DT.TAB_DEC_PACKAGE_DESCRIPTION, \\r
670 DT.TAB_DEC_BINARY_ABSTRACT, DT.TAB_DEC_BINARY_DESCRIPTION]:\r
671 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
672 Message=ST.ERR_UNIPARSE_MULTI_ENTRY_EXIST % StrName.split()[1], \\r
673 ExtraData=File.Path)\r
674 continue\r
675 elif len(Line.split()) == 4 and Line.find(u'#language') > 0:\r
676 if Line[Line.find(u'#language')-1] != ' ' or \\r
677 Line[Line.find(u'#language')+len(u'#language')] != u' ':\r
678 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
679 \r
680 if Line.find(u'"') > 0:\r
681 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
682 \r
683 StrName = Line.split()[0] + u' ' + Line.split()[1]\r
684 if StrName:\r
685 if StrName.split()[1] not in ExistStrNameList:\r
686 ExistStrNameList.append(StrName.split()[1].strip())\r
687 elif StrName.split()[1] in [DT.TAB_INF_ABSTRACT, DT.TAB_INF_DESCRIPTION, \\r
688 DT.TAB_INF_BINARY_ABSTRACT, DT.TAB_INF_BINARY_DESCRIPTION, \\r
689 DT.TAB_DEC_PACKAGE_ABSTRACT, DT.TAB_DEC_PACKAGE_DESCRIPTION, \\r
690 DT.TAB_DEC_BINARY_ABSTRACT, DT.TAB_DEC_BINARY_DESCRIPTION]:\r
691 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
692 Message=ST.ERR_UNIPARSE_MULTI_ENTRY_EXIST % StrName.split()[1], \\r
693 ExtraData=File.Path)\r
694 if IsIncludeFile:\r
695 if StrName not in NewLines:\r
696 NewLines.append((Line[:Line.find(u'#language')]).strip())\r
697 else:\r
698 NewLines.append((Line[:Line.find(u'#language')]).strip())\r
699 NewLines.append((Line[Line.find(u'#language'):]).strip())\r
700 elif len(Line.split()) > 4 and Line.find(u'#language') > 0 and Line.find(u'"') > 0:\r
701 if Line[Line.find(u'#language')-1] != u' ' or \\r
702 Line[Line.find(u'#language')+len(u'#language')] != u' ':\r
703 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
704 \r
705 if Line[Line.find(u'"')-1] != u' ':\r
706 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path) \r
707 \r
708 StrName = Line.split()[0] + u' ' + Line.split()[1] \r
709 if StrName:\r
710 if StrName.split()[1] not in ExistStrNameList:\r
711 ExistStrNameList.append(StrName.split()[1].strip())\r
712 elif StrName.split()[1] in [DT.TAB_INF_ABSTRACT, DT.TAB_INF_DESCRIPTION, \\r
713 DT.TAB_INF_BINARY_ABSTRACT, DT.TAB_INF_BINARY_DESCRIPTION, \\r
714 DT.TAB_DEC_PACKAGE_ABSTRACT, DT.TAB_DEC_PACKAGE_DESCRIPTION, \\r
715 DT.TAB_DEC_BINARY_ABSTRACT, DT.TAB_DEC_BINARY_DESCRIPTION]:\r
716 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
717 Message=ST.ERR_UNIPARSE_MULTI_ENTRY_EXIST % StrName.split()[1], \\r
718 ExtraData=File.Path) \r
719 if IsIncludeFile:\r
720 if StrName not in NewLines:\r
721 NewLines.append((Line[:Line.find(u'#language')]).strip())\r
722 else: \r
723 NewLines.append((Line[:Line.find(u'#language')]).strip())\r
724 NewLines.append((Line[Line.find(u'#language'):Line.find(u'"')]).strip())\r
725 NewLines.append((Line[Line.find(u'"'):]).strip())\r
726 else:\r
727 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
728 elif Line.startswith(u'#language'):\r
729 if len(Line.split()) == 2:\r
730 if IsIncludeFile:\r
731 if StrName not in NewLines:\r
732 NewLines.append(StrName)\r
733 else:\r
734 NewLines.append(StrName)\r
735 NewLines.append(Line)\r
736 elif len(Line.split()) > 2 and Line.find(u'"') > 0:\r
737 if IsIncludeFile:\r
738 if StrName not in NewLines:\r
739 NewLines.append(StrName)\r
740 else:\r
741 NewLines.append(StrName)\r
742 NewLines.append((Line[:Line.find(u'"')]).strip())\r
743 NewLines.append((Line[Line.find(u'"'):]).strip())\r
744 else:\r
745 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
746 elif Line.startswith(u'"'):\r
747 if u'#string' in Line or u'#language' in Line:\r
748 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
749 NewLines.append(Line)\r
750 else:\r
751 print Line\r
752 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
753 \r
754 if StrName and not StrName.split()[1].startswith(u'STR_'):\r
755 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
756 Message=ST.ERR_UNIPARSE_STRNAME_FORMAT_ERROR % StrName.split()[1], \\r
757 ExtraData=File.Path) \r
758 \r
759 if StrName and not NewLines:\r
760 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
761 Message=ST.ERR_UNI_MISS_LANGENTRY % StrName, \\r
762 ExtraData=File.Path)\r
763 \r
764 #\r
765 # Check Abstract, Description, BinaryAbstract and BinaryDescription order,\r
766 # should be Abstract, Description, BinaryAbstract, BinaryDesctiption\r
767 AbstractPosition = -1\r
768 DescriptionPosition = -1\r
769 BinaryAbstractPosition = -1\r
770 BinaryDescriptionPosition = -1\r
771 for StrName in ExistStrNameList:\r
772 if DT.TAB_HEADER_ABSTRACT.upper() in StrName:\r
773 if 'BINARY' in StrName:\r
774 BinaryAbstractPosition = ExistStrNameList.index(StrName)\r
775 else:\r
776 AbstractPosition = ExistStrNameList.index(StrName)\r
777 if DT.TAB_HEADER_DESCRIPTION.upper() in StrName:\r
778 if 'BINARY' in StrName:\r
779 BinaryDescriptionPosition = ExistStrNameList.index(StrName)\r
780 else:\r
781 DescriptionPosition = ExistStrNameList.index(StrName)\r
782 \r
783 OrderList = sorted([AbstractPosition, DescriptionPosition])\r
784 BinaryOrderList = sorted([BinaryAbstractPosition, BinaryDescriptionPosition])\r
785 Min = OrderList[0]\r
786 Max = OrderList[1]\r
787 BinaryMin = BinaryOrderList[0]\r
788 BinaryMax = BinaryOrderList[1]\r
789 if BinaryDescriptionPosition > -1:\r
790 if not(BinaryDescriptionPosition == BinaryMax and BinaryAbstractPosition == BinaryMin and \\r
791 BinaryMax > Max):\r
792 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
793 Message=ST.ERR_UNIPARSE_ENTRY_ORDER_WRONG, \\r
794 ExtraData=File.Path) \r
795 elif BinaryAbstractPosition > -1:\r
796 if not(BinaryAbstractPosition > Max):\r
797 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
798 Message=ST.ERR_UNIPARSE_ENTRY_ORDER_WRONG, \\r
799 ExtraData=File.Path) \r
800 \r
801 if DescriptionPosition > -1:\r
802 if not(DescriptionPosition == Max and AbstractPosition == Min and \\r
803 DescriptionPosition > AbstractPosition):\r
804 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
805 Message=ST.ERR_UNIPARSE_ENTRY_ORDER_WRONG, \\r
806 ExtraData=File.Path) \r
807 \r
808 if not self.UniFileHeader:\r
809 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \r
810 Message = ST.ERR_NO_SOURCE_HEADER,\r
811 ExtraData=File.Path)\r
812 \r
813 return NewLines\r
814\r
815 #\r
816 # Load a .uni file\r
817 #\r
818 def LoadUniFile(self, File = None):\r
819 if File == None:\r
820 EdkLogger.Error("Unicode File Parser", \r
821 ToolError.PARSER_ERROR, \r
822 Message='No unicode file is given', \r
823 ExtraData=File.Path)\r
824 \r
825 self.File = File\r
826 \r
827 #\r
828 # Process special char in file\r
829 #\r
830 Lines = self.PreProcess(File)\r
831\r
832 #\r
833 # Get Unicode Information\r
834 #\r
835 for IndexI in range(len(Lines)):\r
836 Line = Lines[IndexI]\r
837 if (IndexI + 1) < len(Lines):\r
838 SecondLine = Lines[IndexI + 1]\r
839 if (IndexI + 2) < len(Lines):\r
840 ThirdLine = Lines[IndexI + 2]\r
841\r
842 #\r
843 # Get Language def information\r
844 #\r
845 if Line.find(u'#langdef ') >= 0:\r
846 self.GetLangDef(File, Line + u' ' + SecondLine)\r
847 continue\r
848\r
849 Name = ''\r
850 Language = ''\r
851 Value = ''\r
852 CombineToken = False\r
853 #\r
854 # Get string def information format as below\r
855 #\r
856 # #string MY_STRING_1\r
857 # #language eng\r
858 # "My first English string line 1"\r
859 # "My first English string line 2"\r
860 # #string MY_STRING_1\r
861 # #language spa\r
862 # "Mi segunda secuencia 1"\r
863 # "Mi segunda secuencia 2"\r
864 #\r
865 if Line.find(u'#string ') >= 0 and Line.find(u'#language ') < 0 and \\r
866 SecondLine.find(u'#string ') < 0 and SecondLine.find(u'#language ') >= 0 and \\r
867 ThirdLine.find(u'#string ') < 0 and ThirdLine.find(u'#language ') < 0:\r
868 if Line.find('"') > 0 or SecondLine.find('"') > 0:\r
869 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \r
870 Message=ST.ERR_UNIPARSE_DBLQUOTE_UNMATCHED,\r
871 ExtraData=File.Path)\r
872 \r
873 Name = Line[Line.find(u'#string ') + len(u'#string ') : ].strip(' ')\r
874 Language = SecondLine[SecondLine.find(u'#language ') + len(u'#language ') : ].strip(' ')\r
875 for IndexJ in range(IndexI + 2, len(Lines)):\r
876 if Lines[IndexJ].find(u'#string ') < 0 and Lines[IndexJ].find(u'#language ') < 0 and \\r
877 Lines[IndexJ].strip().startswith(u'"') and Lines[IndexJ].strip().endswith(u'"'):\r
878 if Lines[IndexJ][-2] == ' ':\r
879 CombineToken = True\r
880 if CombineToken:\r
881 if Lines[IndexJ].strip()[1:-1].strip():\r
882 Value = Value + Lines[IndexJ].strip()[1:-1].rstrip() + ' '\r
883 else:\r
884 Value = Value + Lines[IndexJ].strip()[1:-1]\r
885 CombineToken = False\r
886 else:\r
cf2b2bde 887 Value = Value + Lines[IndexJ].strip()[1:-1] + '\r\n'\r
421ccda3
HC
888 else:\r
889 IndexI = IndexJ\r
890 break\r
cf2b2bde
HC
891 if Value.endswith('\r\n'):\r
892 Value = Value[: Value.rfind('\r\n')]\r
421ccda3
HC
893 Language = GetLanguageCode(Language, self.IsCompatibleMode, self.File)\r
894 self.AddStringToList(Name, Language, Value)\r
895 continue\r
896\r
897 #\r
898 # Load multiple .uni files\r
899 #\r
900 def LoadUniFiles(self, FileList):\r
901 if len(FileList) > 0:\r
902 for File in FileList:\r
903 FilePath = File.Path.strip()\r
904 if FilePath.endswith('.uni') or FilePath.endswith('.UNI') or FilePath.endswith('.Uni'):\r
905 self.LoadUniFile(File)\r
906\r
907 #\r
908 # Add a string to list\r
909 #\r
910 def AddStringToList(self, Name, Language, Value, Token = 0, Referenced = False, UseOtherLangDef = '', Index = -1):\r
911 for LangNameItem in self.LanguageDef:\r
912 if Language == LangNameItem[0]:\r
913 break\r
914 \r
915 if Language not in self.OrderedStringList:\r
916 self.OrderedStringList[Language] = []\r
917 self.OrderedStringDict[Language] = {}\r
918 \r
919 IsAdded = True\r
920 if Name in self.OrderedStringDict[Language]:\r
921 IsAdded = False\r
922 if Value != None:\r
923 ItemIndexInList = self.OrderedStringDict[Language][Name]\r
924 Item = self.OrderedStringList[Language][ItemIndexInList]\r
925 Item.UpdateValue(Value)\r
926 Item.UseOtherLangDef = '' \r
927\r
928 if IsAdded:\r
929 Token = len(self.OrderedStringList[Language])\r
930 if Index == -1:\r
931 self.OrderedStringList[Language].append(StringDefClassObject(Name, \r
932 Value, \r
933 Referenced, \r
934 Token, \r
935 UseOtherLangDef))\r
936 self.OrderedStringDict[Language][Name] = Token\r
937 for LangName in self.LanguageDef:\r
938 #\r
939 # New STRING token will be added into all language string lists.\r
940 # so that the unique STRING identifier is reserved for all languages in the package list. \r
941 #\r
942 if LangName[0] != Language:\r
943 if UseOtherLangDef != '':\r
944 OtherLangDef = UseOtherLangDef\r
945 else:\r
946 OtherLangDef = Language\r
947 self.OrderedStringList[LangName[0]].append(StringDefClassObject(Name, \r
948 '', \r
949 Referenced, \r
950 Token, \r
951 OtherLangDef))\r
952 self.OrderedStringDict[LangName[0]][Name] = len(self.OrderedStringList[LangName[0]]) - 1\r
953 else:\r
954 self.OrderedStringList[Language].insert(Index, StringDefClassObject(Name, \r
955 Value, \r
956 Referenced, \r
957 Token, \r
958 UseOtherLangDef))\r
959 self.OrderedStringDict[Language][Name] = Index\r
960\r
961 #\r
962 # Set the string as referenced\r
963 #\r
964 def SetStringReferenced(self, Name):\r
965 #\r
966 # String stoken are added in the same order in all language string lists.\r
967 # So, only update the status of string stoken in first language string list.\r
968 #\r
969 Lang = self.LanguageDef[0][0]\r
970 if Name in self.OrderedStringDict[Lang]:\r
971 ItemIndexInList = self.OrderedStringDict[Lang][Name]\r
972 Item = self.OrderedStringList[Lang][ItemIndexInList]\r
973 Item.Referenced = True\r
974\r
975 #\r
976 # Search the string in language definition by Name\r
977 #\r
978 def FindStringValue(self, Name, Lang):\r
979 if Name in self.OrderedStringDict[Lang]:\r
980 ItemIndexInList = self.OrderedStringDict[Lang][Name]\r
981 return self.OrderedStringList[Lang][ItemIndexInList]\r
982\r
983 return None\r
984\r
985 #\r
986 # Search the string in language definition by Token\r
987 #\r
988 def FindByToken(self, Token, Lang):\r
989 for Item in self.OrderedStringList[Lang]:\r
990 if Item.Token == Token:\r
991 return Item\r
992\r
993 return None\r
994\r
995 #\r
996 # Re-order strings and re-generate tokens\r
997 #\r
998 def ReToken(self):\r
999 if len(self.LanguageDef) == 0:\r
1000 return None\r
1001 #\r
1002 # Retoken all language strings according to the status of string stoken in the first language string.\r
1003 #\r
1004 FirstLangName = self.LanguageDef[0][0]\r
1005\r
1006 # Convert the OrderedStringList to be OrderedStringListByToken in order to faciliate future search by token\r
1007 for LangNameItem in self.LanguageDef:\r
1008 self.OrderedStringListByToken[LangNameItem[0]] = {}\r
1009\r
1010 #\r
1011 # Use small token for all referred string stoken.\r
1012 #\r
1013 RefToken = 0\r
1014 for Index in range (0, len (self.OrderedStringList[FirstLangName])):\r
1015 FirstLangItem = self.OrderedStringList[FirstLangName][Index]\r
1016 if FirstLangItem.Referenced == True:\r
1017 for LangNameItem in self.LanguageDef:\r
1018 LangName = LangNameItem[0]\r
1019 OtherLangItem = self.OrderedStringList[LangName][Index]\r
1020 OtherLangItem.Referenced = True\r
1021 OtherLangItem.Token = RefToken\r
1022 self.OrderedStringListByToken[LangName][OtherLangItem.Token] = OtherLangItem\r
1023 RefToken = RefToken + 1\r
1024\r
1025 #\r
1026 # Use big token for all unreferred string stoken.\r
1027 #\r
1028 UnRefToken = 0\r
1029 for Index in range (0, len (self.OrderedStringList[FirstLangName])):\r
1030 FirstLangItem = self.OrderedStringList[FirstLangName][Index]\r
1031 if FirstLangItem.Referenced == False:\r
1032 for LangNameItem in self.LanguageDef:\r
1033 LangName = LangNameItem[0]\r
1034 OtherLangItem = self.OrderedStringList[LangName][Index]\r
1035 OtherLangItem.Token = RefToken + UnRefToken\r
1036 self.OrderedStringListByToken[LangName][OtherLangItem.Token] = OtherLangItem\r
1037 UnRefToken = UnRefToken + 1\r
1038\r
1039 #\r
1040 # Show the instance itself\r
1041 #\r
1042 def ShowMe(self):\r
1043 print self.LanguageDef\r
1044 #print self.OrderedStringList\r
1045 for Item in self.OrderedStringList:\r
1046 print Item\r
1047 for Member in self.OrderedStringList[Item]:\r
1048 print str(Member)\r
1049 \r
1050 #\r
1051 # Read content from '!include' UNI file \r
1052 #\r
1053 def ReadIncludeUNIfile(self, FilaPath):\r
1054 if self.File:\r
1055 pass\r
1056 \r
1057 if not os.path.exists(FilaPath) or not os.path.isfile(FilaPath):\r
1058 EdkLogger.Error("Unicode File Parser", \r
1059 ToolError.FILE_NOT_FOUND,\r
1060 ExtraData=FilaPath)\r
1061 try:\r
645a5128 1062 FileIn = codecs.open(FilaPath, mode='rb', encoding='utf_8').readlines()\r
4a21fb3b 1063 except UnicodeError, Xstr:\r
421ccda3
HC
1064 FileIn = codecs.open(FilaPath, mode='rb', encoding='utf_16').readlines()\r
1065 except UnicodeError:\r
1066 FileIn = codecs.open(FilaPath, mode='rb', encoding='utf_16_le').readlines()\r
1067 except:\r
1068 EdkLogger.Error("Unicode File Parser", ToolError.FILE_OPEN_FAILURE, ExtraData=FilaPath)\r
1069 return FileIn\r
1070\r