]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/UPT/Library/UniClassObject.py
BaseTools: Clean up source 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
b3fa393f 4# Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>\r
421ccda3 5#\r
f7496d71
LG
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
421ccda3
HC
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
72443dd2 17from __future__ import print_function\r
421ccda3
HC
18\r
19##\r
20# Import Modules\r
21#\r
22import os, codecs, re\r
23import distutils.util\r
24from Logger import ToolError\r
25from Logger import Log as EdkLogger\r
26from Logger import StringTable as ST\r
64285f15 27from Library.StringUtils import GetLineNo\r
421ccda3
HC
28from Library.Misc import PathClass\r
29from Library.Misc import GetCharIndexOutStr\r
30from Library import DataType as DT\r
fe90f483 31from Library.ParserValidate import CheckUTF16FileHeader\r
421ccda3
HC
32\r
33##\r
34# Static definitions\r
35#\r
36UNICODE_WIDE_CHAR = u'\\wide'\r
37UNICODE_NARROW_CHAR = u'\\narrow'\r
38UNICODE_NON_BREAKING_CHAR = u'\\nbr'\r
39UNICODE_UNICODE_CR = '\r'\r
40UNICODE_UNICODE_LF = '\n'\r
41\r
42NARROW_CHAR = u'\uFFF0'\r
43WIDE_CHAR = u'\uFFF1'\r
44NON_BREAKING_CHAR = u'\uFFF2'\r
45CR = u'\u000D'\r
46LF = u'\u000A'\r
47NULL = u'\u0000'\r
48TAB = u'\t'\r
49BACK_SPLASH = u'\\'\r
50\r
421ccda3
HC
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
fe90f483
HC
139 return LangName\r
140\r
421ccda3
HC
141 length = len(LangName)\r
142 if length == 2:\r
143 if LangName.isalpha():\r
144 for Key in gLANG_CONV_TABLE.keys():\r
145 if gLANG_CONV_TABLE.get(Key) == LangName.lower():\r
146 return Key\r
147 elif length == 3:\r
148 if LangName.isalpha() and gLANG_CONV_TABLE.get(LangName.lower()):\r
149 return LangName\r
150 else:\r
f7496d71 151 EdkLogger.Error("Unicode File Parser",\r
421ccda3 152 ToolError.FORMAT_INVALID,\r
f7496d71 153 "Invalid RFC 1766 language code : %s" % LangName,\r
421ccda3
HC
154 File)\r
155 elif length == 5:\r
156 if LangName[0:2].isalpha() and LangName[2] == '-':\r
157 for Key in gLANG_CONV_TABLE.keys():\r
158 if gLANG_CONV_TABLE.get(Key) == LangName[0:2].lower():\r
159 return Key\r
160 elif length >= 6:\r
161 if LangName[0:2].isalpha() and LangName[2] == '-':\r
162 for Key in gLANG_CONV_TABLE.keys():\r
163 if gLANG_CONV_TABLE.get(Key) == LangName[0:2].lower():\r
164 return Key\r
4231a819 165 if LangName[0:3].isalpha() and gLANG_CONV_TABLE.get(LangName.lower()) is None and LangName[3] == '-':\r
421ccda3
HC
166 for Key in gLANG_CONV_TABLE.keys():\r
167 if Key == LangName[0:3].lower():\r
168 return Key\r
169\r
f7496d71 170 EdkLogger.Error("Unicode File Parser",\r
421ccda3 171 ToolError.FORMAT_INVALID,\r
f7496d71 172 "Invalid RFC 4646 language code : %s" % LangName,\r
421ccda3 173 File)\r
f7496d71 174\r
421ccda3
HC
175## GetLanguageCode\r
176#\r
177# Check the language code read from .UNI file and convert RFC 1766 codes to RFC 4646 codes if appropriate\r
178# RFC 1766 language codes supported in compatiblity mode\r
179# RFC 4646 language codes supported in native mode\r
180#\r
181# @param LangName: Language codes read from .UNI file\r
182#\r
183# @retval LangName: Valid lanugage code in RFC 4646 format or None\r
184#\r
185def GetLanguageCode(LangName, IsCompatibleMode, File):\r
186 length = len(LangName)\r
187 if IsCompatibleMode:\r
188 if length == 3 and LangName.isalpha():\r
189 TempLangName = gLANG_CONV_TABLE.get(LangName.lower())\r
4231a819 190 if TempLangName is not None:\r
421ccda3
HC
191 return TempLangName\r
192 return LangName\r
193 else:\r
f7496d71 194 EdkLogger.Error("Unicode File Parser",\r
421ccda3 195 ToolError.FORMAT_INVALID,\r
f7496d71 196 "Invalid RFC 1766 language code : %s" % LangName,\r
421ccda3
HC
197 File)\r
198 if (LangName[0] == 'X' or LangName[0] == 'x') and LangName[1] == '-':\r
199 return LangName\r
200 if length == 2:\r
201 if LangName.isalpha():\r
202 return LangName\r
203 elif length == 3:\r
4231a819 204 if LangName.isalpha() and gLANG_CONV_TABLE.get(LangName.lower()) is None:\r
421ccda3
HC
205 return LangName\r
206 elif length == 5:\r
207 if LangName[0:2].isalpha() and LangName[2] == '-':\r
208 return LangName\r
209 elif length >= 6:\r
210 if LangName[0:2].isalpha() and LangName[2] == '-':\r
211 return LangName\r
4231a819 212 if LangName[0:3].isalpha() and gLANG_CONV_TABLE.get(LangName.lower()) is None and LangName[3] == '-':\r
421ccda3
HC
213 return LangName\r
214\r
f7496d71 215 EdkLogger.Error("Unicode File Parser",\r
421ccda3 216 ToolError.FORMAT_INVALID,\r
f7496d71 217 "Invalid RFC 4646 language code : %s" % LangName,\r
421ccda3
HC
218 File)\r
219\r
220## FormatUniEntry\r
221#\r
222# Formated the entry in Uni file.\r
223#\r
224# @param StrTokenName StrTokenName.\r
225# @param TokenValueList A list need to be processed.\r
226# @param ContainerFile ContainerFile.\r
227#\r
228# @return formated entry\r
229def FormatUniEntry(StrTokenName, TokenValueList, ContainerFile):\r
230 SubContent = ''\r
231 PreFormatLength = 40\r
232 if len(StrTokenName) > PreFormatLength:\r
233 PreFormatLength = len(StrTokenName) + 1\r
f7496d71 234 for (Lang, Value) in TokenValueList:\r
421ccda3
HC
235 if not Value or Lang == DT.TAB_LANGUAGE_EN_X:\r
236 continue\r
237 if Lang == '':\r
238 Lang = DT.TAB_LANGUAGE_EN_US\r
239 if Lang == 'eng':\r
240 Lang = DT.TAB_LANGUAGE_EN_US\r
241 elif len(Lang.split('-')[0]) == 3:\r
242 Lang = GetLanguageCode(Lang.split('-')[0], True, ContainerFile)\r
243 else:\r
244 Lang = GetLanguageCode(Lang, False, ContainerFile)\r
245 ValueList = Value.split('\n')\r
246 SubValueContent = ''\r
247 for SubValue in ValueList:\r
248 if SubValue.strip():\r
249 SubValueContent += \\r
cf2b2bde
HC
250 ' ' * (PreFormatLength + len('#language en-US ')) + '\"%s\\n\"' % SubValue.strip() + '\r\n'\r
251 SubValueContent = SubValueContent[(PreFormatLength + len('#language en-US ')):SubValueContent.rfind('\\n')] \\r
252 + '\"' + '\r\n'\r
421ccda3
HC
253 SubContent += ' '*PreFormatLength + '#language %-5s ' % Lang + SubValueContent\r
254 if SubContent:\r
255 SubContent = StrTokenName + ' '*(PreFormatLength - len(StrTokenName)) + SubContent[PreFormatLength:]\r
256 return SubContent\r
257\r
258\r
259## StringDefClassObject\r
260#\r
261# A structure for language definition\r
262#\r
263class StringDefClassObject(object):\r
264 def __init__(self, Name = None, Value = None, Referenced = False, Token = None, UseOtherLangDef = ''):\r
265 self.StringName = ''\r
266 self.StringNameByteList = []\r
267 self.StringValue = ''\r
268 self.StringValueByteList = ''\r
269 self.Token = 0\r
270 self.Referenced = Referenced\r
271 self.UseOtherLangDef = UseOtherLangDef\r
272 self.Length = 0\r
273\r
4231a819 274 if Name is not None:\r
421ccda3
HC
275 self.StringName = Name\r
276 self.StringNameByteList = UniToHexList(Name)\r
4231a819 277 if Value is not None:\r
421ccda3
HC
278 self.StringValue = Value\r
279 self.StringValueByteList = UniToHexList(self.StringValue)\r
280 self.Length = len(self.StringValueByteList)\r
4231a819 281 if Token is not None:\r
421ccda3
HC
282 self.Token = Token\r
283\r
284 def __str__(self):\r
285 return repr(self.StringName) + ' ' + \\r
286 repr(self.Token) + ' ' + \\r
287 repr(self.Referenced) + ' ' + \\r
288 repr(self.StringValue) + ' ' + \\r
289 repr(self.UseOtherLangDef)\r
290\r
291 def UpdateValue(self, Value = None):\r
4231a819 292 if Value is not None:\r
421ccda3 293 if self.StringValue:\r
cf2b2bde 294 self.StringValue = self.StringValue + '\r\n' + Value\r
421ccda3
HC
295 else:\r
296 self.StringValue = Value\r
297 self.StringValueByteList = UniToHexList(self.StringValue)\r
298 self.Length = len(self.StringValueByteList)\r
299\r
300## UniFileClassObject\r
301#\r
302# A structure for .uni file definition\r
303#\r
304class UniFileClassObject(object):\r
305 def __init__(self, FileList = None, IsCompatibleMode = False, IncludePathList = None):\r
306 self.FileList = FileList\r
307 self.File = None\r
308 self.IncFileList = FileList\r
309 self.UniFileHeader = ''\r
310 self.Token = 2\r
311 self.LanguageDef = [] #[ [u'LanguageIdentifier', u'PrintableName'], ... ]\r
312 self.OrderedStringList = {} #{ u'LanguageIdentifier' : [StringDefClassObject] }\r
313 self.OrderedStringDict = {} #{ u'LanguageIdentifier' : {StringName:(IndexInList)} }\r
314 self.OrderedStringListByToken = {} #{ u'LanguageIdentifier' : {Token: StringDefClassObject} }\r
315 self.IsCompatibleMode = IsCompatibleMode\r
316 if not IncludePathList:\r
317 self.IncludePathList = []\r
318 else:\r
319 self.IncludePathList = IncludePathList\r
320 if len(self.FileList) > 0:\r
321 self.LoadUniFiles(FileList)\r
322\r
323 #\r
324 # Get Language definition\r
325 #\r
326 def GetLangDef(self, File, Line):\r
327 Lang = distutils.util.split_quoted((Line.split(u"//")[0]))\r
328 if len(Lang) != 3:\r
329 try:\r
645a5128 330 FileIn = codecs.open(File.Path, mode='rb', encoding='utf_8').readlines()\r
5b0671c1 331 except UnicodeError as Xstr:\r
645a5128 332 FileIn = codecs.open(File.Path, mode='rb', encoding='utf_16').readlines()\r
5b0671c1 333 except UnicodeError as Xstr:\r
645a5128 334 FileIn = codecs.open(File.Path, mode='rb', encoding='utf_16_le').readlines()\r
421ccda3 335 except:\r
f7496d71
LG
336 EdkLogger.Error("Unicode File Parser",\r
337 ToolError.FILE_OPEN_FAILURE,\r
421ccda3
HC
338 "File read failure: %s" % str(Xstr),\r
339 ExtraData=File)\r
340 LineNo = GetLineNo(FileIn, Line, False)\r
f7496d71 341 EdkLogger.Error("Unicode File Parser",\r
421ccda3 342 ToolError.PARSER_ERROR,\r
f7496d71
LG
343 "Wrong language definition",\r
344 ExtraData="""%s\n\t*Correct format is like '#langdef en-US "English"'""" % Line,\r
421ccda3
HC
345 File = File, Line = LineNo)\r
346 else:\r
347 LangName = GetLanguageCode(Lang[1], self.IsCompatibleMode, self.File)\r
348 LangPrintName = Lang[2]\r
349\r
350 IsLangInDef = False\r
351 for Item in self.LanguageDef:\r
352 if Item[0] == LangName:\r
353 IsLangInDef = True\r
354 break\r
355\r
356 if not IsLangInDef:\r
357 self.LanguageDef.append([LangName, LangPrintName])\r
358\r
359 #\r
360 # Add language string\r
361 #\r
362 self.AddStringToList(u'$LANGUAGE_NAME', LangName, LangName, 0, True, Index=0)\r
363 self.AddStringToList(u'$PRINTABLE_LANGUAGE_NAME', LangName, LangPrintName, 1, True, Index=1)\r
364\r
365 if not IsLangInDef:\r
366 #\r
367 # The found STRING tokens will be added into new language string list\r
f7496d71 368 # so that the unique STRING identifier is reserved for all languages in the package list.\r
421ccda3
HC
369 #\r
370 FirstLangName = self.LanguageDef[0][0]\r
371 if LangName != FirstLangName:\r
372 for Index in range (2, len (self.OrderedStringList[FirstLangName])):\r
373 Item = self.OrderedStringList[FirstLangName][Index]\r
374 if Item.UseOtherLangDef != '':\r
375 OtherLang = Item.UseOtherLangDef\r
376 else:\r
377 OtherLang = FirstLangName\r
f7496d71
LG
378 self.OrderedStringList[LangName].append (StringDefClassObject(Item.StringName,\r
379 '',\r
380 Item.Referenced,\r
381 Item.Token,\r
421ccda3
HC
382 OtherLang))\r
383 self.OrderedStringDict[LangName][Item.StringName] = len(self.OrderedStringList[LangName]) - 1\r
384 return True\r
385\r
386 #\r
387 # Get String name and value\r
388 #\r
389 def GetStringObject(self, Item):\r
390 Language = ''\r
391 Value = ''\r
392\r
393 Name = Item.split()[1]\r
394 # Check the string name is the upper character\r
395 if Name != '':\r
396 MatchString = re.match('[A-Z0-9_]+', Name, re.UNICODE)\r
4231a819 397 if MatchString is None or MatchString.end(0) != len(Name):\r
f7496d71 398 EdkLogger.Error("Unicode File Parser",\r
421ccda3
HC
399 ToolError.FORMAT_INVALID,\r
400 'The string token name %s in UNI file %s must be upper case character.' %(Name, self.File))\r
401 LanguageList = Item.split(u'#language ')\r
402 for IndexI in range(len(LanguageList)):\r
403 if IndexI == 0:\r
404 continue\r
405 else:\r
406 Language = LanguageList[IndexI].split()[0]\r
407 #.replace(u'\r\n', u'')\r
408 Value = \\r
f7496d71 409 LanguageList[IndexI][LanguageList[IndexI].find(u'\"') + len(u'\"') : LanguageList[IndexI].rfind(u'\"')]\r
421ccda3
HC
410 Language = GetLanguageCode(Language, self.IsCompatibleMode, self.File)\r
411 self.AddStringToList(Name, Language, Value)\r
412\r
413 #\r
414 # Get include file list and load them\r
415 #\r
416 def GetIncludeFile(self, Item, Dir = None):\r
417 if Dir:\r
418 pass\r
419 FileName = Item[Item.find(u'!include ') + len(u'!include ') :Item.find(u' ', len(u'!include '))][1:-1]\r
420 self.LoadUniFile(FileName)\r
421\r
422 #\r
423 # Pre-process before parse .uni file\r
424 #\r
425 def PreProcess(self, File, IsIncludeFile=False):\r
426 if not os.path.exists(File.Path) or not os.path.isfile(File.Path):\r
f7496d71 427 EdkLogger.Error("Unicode File Parser",\r
421ccda3
HC
428 ToolError.FILE_NOT_FOUND,\r
429 ExtraData=File.Path)\r
430\r
fe90f483
HC
431 #\r
432 # Check file header of the Uni file\r
433 #\r
4a21fb3b
HC
434# if not CheckUTF16FileHeader(File.Path):\r
435# EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID,\r
436# ExtraData='The file %s is either invalid UTF-16LE or it is missing the BOM.' % File.Path)\r
fe90f483 437\r
421ccda3 438 try:\r
645a5128 439 FileIn = codecs.open(File.Path, mode='rb', encoding='utf_8').readlines()\r
5b0671c1 440 except UnicodeError as Xstr:\r
421ccda3
HC
441 FileIn = codecs.open(File.Path, mode='rb', encoding='utf_16').readlines()\r
442 except UnicodeError:\r
443 FileIn = codecs.open(File.Path, mode='rb', encoding='utf_16_le').readlines()\r
444 except:\r
445 EdkLogger.Error("Unicode File Parser", ToolError.FILE_OPEN_FAILURE, ExtraData=File.Path)\r
f7496d71
LG
446\r
447\r
421ccda3
HC
448 #\r
449 # get the file header\r
450 #\r
451 Lines = []\r
452 HeaderStart = False\r
453 HeaderEnd = False\r
454 if not self.UniFileHeader:\r
455 FirstGenHeader = True\r
456 else:\r
457 FirstGenHeader = False\r
458 for Line in FileIn:\r
459 Line = Line.strip()\r
460 if Line == u'':\r
461 continue\r
462 if Line.startswith(DT.TAB_COMMENT_EDK1_SPLIT) and (Line.find(DT.TAB_HEADER_COMMENT) > -1) \\r
463 and not HeaderEnd and not HeaderStart:\r
464 HeaderStart = True\r
465 if not Line.startswith(DT.TAB_COMMENT_EDK1_SPLIT) and HeaderStart and not HeaderEnd:\r
466 HeaderEnd = True\r
467 if Line.startswith(DT.TAB_COMMENT_EDK1_SPLIT) and HeaderStart and not HeaderEnd and FirstGenHeader:\r
cf2b2bde 468 self.UniFileHeader += Line + '\r\n'\r
421ccda3 469 continue\r
f7496d71 470\r
421ccda3
HC
471 #\r
472 # Use unique identifier\r
473 #\r
474 FindFlag = -1\r
475 LineCount = 0\r
476 MultiLineFeedExits = False\r
477 #\r
478 # 0: initial value\r
479 # 1: signle String entry exist\r
480 # 2: line feed exist under the some signle String entry\r
481 #\r
482 StringEntryExistsFlag = 0\r
483 for Line in FileIn:\r
484 Line = FileIn[LineCount]\r
485 LineCount += 1\r
486 Line = Line.strip()\r
487 #\r
488 # Ignore comment line and empty line\r
f7496d71 489 #\r
421ccda3
HC
490 if Line == u'' or Line.startswith(u'//'):\r
491 #\r
492 # Change the single line String entry flag status\r
493 #\r
494 if StringEntryExistsFlag == 1:\r
495 StringEntryExistsFlag = 2\r
496 #\r
497 # If the '#string' line and the '#language' line are not in the same line,\r
498 # there should be only one line feed character betwwen them\r
499 #\r
500 if MultiLineFeedExits:\r
501 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
502 continue\r
503\r
504 MultiLineFeedExits = False\r
505 #\r
506 # Process comment embeded in string define lines\r
507 #\r
508 FindFlag = Line.find(u'//')\r
509 if FindFlag != -1 and Line.find(u'//') < Line.find(u'"'):\r
510 Line = Line.replace(Line[FindFlag:], u' ')\r
511 if FileIn[LineCount].strip().startswith('#language'):\r
512 Line = Line + FileIn[LineCount]\r
513 FileIn[LineCount-1] = Line\r
cf2b2bde 514 FileIn[LineCount] = '\r\n'\r
421ccda3
HC
515 LineCount -= 1\r
516 for Index in xrange (LineCount + 1, len (FileIn) - 1):\r
517 if (Index == len(FileIn) -1):\r
cf2b2bde 518 FileIn[Index] = '\r\n'\r
421ccda3
HC
519 else:\r
520 FileIn[Index] = FileIn[Index + 1]\r
521 continue\r
522 CommIndex = GetCharIndexOutStr(u'/', Line)\r
523 if CommIndex > -1:\r
524 if (len(Line) - 1) > CommIndex:\r
525 if Line[CommIndex+1] == u'/':\r
526 Line = Line[:CommIndex].strip()\r
527 else:\r
528 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
529 else:\r
530 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
f7496d71 531\r
421ccda3
HC
532 Line = Line.replace(UNICODE_WIDE_CHAR, WIDE_CHAR)\r
533 Line = Line.replace(UNICODE_NARROW_CHAR, NARROW_CHAR)\r
534 Line = Line.replace(UNICODE_NON_BREAKING_CHAR, NON_BREAKING_CHAR)\r
535\r
536 Line = Line.replace(u'\\\\', u'\u0006')\r
537 Line = Line.replace(u'\\r\\n', CR + LF)\r
538 Line = Line.replace(u'\\n', CR + LF)\r
539 Line = Line.replace(u'\\r', CR)\r
540 Line = Line.replace(u'\\t', u'\t')\r
541 Line = Line.replace(u'''\"''', u'''"''')\r
542 Line = Line.replace(u'\t', u' ')\r
543 Line = Line.replace(u'\u0006', u'\\')\r
544\r
85ea493f
HC
545 #\r
546 # Check if single line has correct '"'\r
547 #\r
548 if Line.startswith(u'#string') and Line.find(u'#language') > -1 and Line.find('"') > Line.find(u'#language'):\r
549 if not Line.endswith('"'):\r
550 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID,\r
551 ExtraData='''The line %s misses '"' at the end of it in file %s'''\r
552 % (LineCount, File.Path))\r
553\r
421ccda3
HC
554 #\r
555 # Between Name entry and Language entry can not contain line feed\r
556 #\r
557 if Line.startswith(u'#string') and Line.find(u'#language') == -1:\r
558 MultiLineFeedExits = True\r
f7496d71 559\r
421ccda3
HC
560 if Line.startswith(u'#string') and Line.find(u'#language') > 0 and Line.find(u'"') < 0:\r
561 MultiLineFeedExits = True\r
f7496d71 562\r
421ccda3
HC
563 #\r
564 # Between Language entry and String entry can not contain line feed\r
565 #\r
566 if Line.startswith(u'#language') and len(Line.split()) == 2:\r
567 MultiLineFeedExits = True\r
f7496d71 568\r
421ccda3
HC
569 #\r
570 # Between two String entry, can not contain line feed\r
571 #\r
572 if Line.startswith(u'"'):\r
573 if StringEntryExistsFlag == 2:\r
645a5128 574 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID,\r
421ccda3 575 Message=ST.ERR_UNIPARSE_LINEFEED_UP_EXIST % Line, ExtraData=File.Path)\r
645a5128 576\r
421ccda3
HC
577 StringEntryExistsFlag = 1\r
578 if not Line.endswith('"'):\r
fe90f483
HC
579 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID,\r
580 ExtraData='''The line %s misses '"' at the end of it in file %s'''\r
581 % (LineCount, File.Path))\r
421ccda3
HC
582 elif Line.startswith(u'#language'):\r
583 if StringEntryExistsFlag == 2:\r
645a5128 584 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID,\r
fe90f483 585 Message=ST.ERR_UNI_MISS_STRING_ENTRY % Line, ExtraData=File.Path)\r
421ccda3
HC
586 StringEntryExistsFlag = 0\r
587 else:\r
588 StringEntryExistsFlag = 0\r
589\r
590 Lines.append(Line)\r
f7496d71 591\r
421ccda3
HC
592 #\r
593 # Convert string def format as below\r
594 #\r
595 # #string MY_STRING_1\r
596 # #language eng\r
597 # "My first English string line 1"\r
598 # "My first English string line 2"\r
599 # #string MY_STRING_1\r
600 # #language spa\r
601 # "Mi segunda secuencia 1"\r
602 # "Mi segunda secuencia 2"\r
603 #\r
f7496d71 604\r
421ccda3
HC
605 if not IsIncludeFile and not Lines:\r
606 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
607 Message=ST.ERR_UNIPARSE_NO_SECTION_EXIST, \\r
f7496d71 608 ExtraData=File.Path)\r
421ccda3
HC
609\r
610 NewLines = []\r
611 StrName = u''\r
612 ExistStrNameList = []\r
613 for Line in Lines:\r
614 if StrName and not StrName.split()[1].startswith(DT.TAB_STR_TOKENCNAME + DT.TAB_UNDERLINE_SPLIT):\r
615 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
616 Message=ST.ERR_UNIPARSE_STRNAME_FORMAT_ERROR % StrName.split()[1], \\r
617 ExtraData=File.Path)\r
f7496d71 618\r
421ccda3
HC
619 if StrName and len(StrName.split()[1].split(DT.TAB_UNDERLINE_SPLIT)) == 4:\r
620 StringTokenList = StrName.split()[1].split(DT.TAB_UNDERLINE_SPLIT)\r
621 if (StringTokenList[3].upper() in [DT.TAB_STR_TOKENPROMPT, DT.TAB_STR_TOKENHELP] and \\r
622 StringTokenList[3] not in [DT.TAB_STR_TOKENPROMPT, DT.TAB_STR_TOKENHELP]) or \\r
623 (StringTokenList[2].upper() == DT.TAB_STR_TOKENERR and StringTokenList[2] != DT.TAB_STR_TOKENERR):\r
624 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
625 Message=ST.ERR_UNIPARSE_STRTOKEN_FORMAT_ERROR % StrName.split()[1], \\r
626 ExtraData=File.Path)\r
f7496d71 627\r
421ccda3
HC
628 if Line.count(u'#language') > 1:\r
629 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
630 Message=ST.ERR_UNIPARSE_SEP_LANGENTRY_LINE % Line, \\r
f7496d71
LG
631 ExtraData=File.Path)\r
632\r
421ccda3
HC
633 if Line.startswith(u'//'):\r
634 continue\r
635 elif Line.startswith(u'#langdef'):\r
636 if len(Line.split()) == 2:\r
637 NewLines.append(Line)\r
638 continue\r
f7496d71 639 elif len(Line.split()) > 2 and Line.find(u'"') > 0:\r
421ccda3
HC
640 NewLines.append(Line[:Line.find(u'"')].strip())\r
641 NewLines.append(Line[Line.find(u'"'):])\r
642 else:\r
643 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
644 elif Line.startswith(u'#string'):\r
645 if len(Line.split()) == 2:\r
646 StrName = Line\r
647 if StrName:\r
648 if StrName.split()[1] not in ExistStrNameList:\r
649 ExistStrNameList.append(StrName.split()[1].strip())\r
650 elif StrName.split()[1] in [DT.TAB_INF_ABSTRACT, DT.TAB_INF_DESCRIPTION, \\r
651 DT.TAB_INF_BINARY_ABSTRACT, DT.TAB_INF_BINARY_DESCRIPTION, \\r
652 DT.TAB_DEC_PACKAGE_ABSTRACT, DT.TAB_DEC_PACKAGE_DESCRIPTION, \\r
653 DT.TAB_DEC_BINARY_ABSTRACT, DT.TAB_DEC_BINARY_DESCRIPTION]:\r
654 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
655 Message=ST.ERR_UNIPARSE_MULTI_ENTRY_EXIST % StrName.split()[1], \\r
656 ExtraData=File.Path)\r
657 continue\r
658 elif len(Line.split()) == 4 and Line.find(u'#language') > 0:\r
659 if Line[Line.find(u'#language')-1] != ' ' or \\r
660 Line[Line.find(u'#language')+len(u'#language')] != u' ':\r
661 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
f7496d71 662\r
421ccda3
HC
663 if Line.find(u'"') > 0:\r
664 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
f7496d71 665\r
421ccda3
HC
666 StrName = Line.split()[0] + u' ' + Line.split()[1]\r
667 if StrName:\r
668 if StrName.split()[1] not in ExistStrNameList:\r
669 ExistStrNameList.append(StrName.split()[1].strip())\r
670 elif StrName.split()[1] in [DT.TAB_INF_ABSTRACT, DT.TAB_INF_DESCRIPTION, \\r
671 DT.TAB_INF_BINARY_ABSTRACT, DT.TAB_INF_BINARY_DESCRIPTION, \\r
672 DT.TAB_DEC_PACKAGE_ABSTRACT, DT.TAB_DEC_PACKAGE_DESCRIPTION, \\r
673 DT.TAB_DEC_BINARY_ABSTRACT, DT.TAB_DEC_BINARY_DESCRIPTION]:\r
674 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
675 Message=ST.ERR_UNIPARSE_MULTI_ENTRY_EXIST % StrName.split()[1], \\r
676 ExtraData=File.Path)\r
677 if IsIncludeFile:\r
678 if StrName not in NewLines:\r
679 NewLines.append((Line[:Line.find(u'#language')]).strip())\r
680 else:\r
681 NewLines.append((Line[:Line.find(u'#language')]).strip())\r
682 NewLines.append((Line[Line.find(u'#language'):]).strip())\r
683 elif len(Line.split()) > 4 and Line.find(u'#language') > 0 and Line.find(u'"') > 0:\r
684 if Line[Line.find(u'#language')-1] != u' ' or \\r
685 Line[Line.find(u'#language')+len(u'#language')] != u' ':\r
686 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
f7496d71 687\r
421ccda3 688 if Line[Line.find(u'"')-1] != u' ':\r
f7496d71
LG
689 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
690\r
691 StrName = Line.split()[0] + u' ' + Line.split()[1]\r
421ccda3
HC
692 if StrName:\r
693 if StrName.split()[1] not in ExistStrNameList:\r
694 ExistStrNameList.append(StrName.split()[1].strip())\r
695 elif StrName.split()[1] in [DT.TAB_INF_ABSTRACT, DT.TAB_INF_DESCRIPTION, \\r
696 DT.TAB_INF_BINARY_ABSTRACT, DT.TAB_INF_BINARY_DESCRIPTION, \\r
697 DT.TAB_DEC_PACKAGE_ABSTRACT, DT.TAB_DEC_PACKAGE_DESCRIPTION, \\r
698 DT.TAB_DEC_BINARY_ABSTRACT, DT.TAB_DEC_BINARY_DESCRIPTION]:\r
699 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
700 Message=ST.ERR_UNIPARSE_MULTI_ENTRY_EXIST % StrName.split()[1], \\r
f7496d71 701 ExtraData=File.Path)\r
421ccda3
HC
702 if IsIncludeFile:\r
703 if StrName not in NewLines:\r
704 NewLines.append((Line[:Line.find(u'#language')]).strip())\r
f7496d71 705 else:\r
421ccda3
HC
706 NewLines.append((Line[:Line.find(u'#language')]).strip())\r
707 NewLines.append((Line[Line.find(u'#language'):Line.find(u'"')]).strip())\r
708 NewLines.append((Line[Line.find(u'"'):]).strip())\r
709 else:\r
710 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
711 elif Line.startswith(u'#language'):\r
712 if len(Line.split()) == 2:\r
713 if IsIncludeFile:\r
714 if StrName not in NewLines:\r
715 NewLines.append(StrName)\r
716 else:\r
717 NewLines.append(StrName)\r
718 NewLines.append(Line)\r
719 elif len(Line.split()) > 2 and Line.find(u'"') > 0:\r
720 if IsIncludeFile:\r
721 if StrName not in NewLines:\r
722 NewLines.append(StrName)\r
723 else:\r
724 NewLines.append(StrName)\r
725 NewLines.append((Line[:Line.find(u'"')]).strip())\r
726 NewLines.append((Line[Line.find(u'"'):]).strip())\r
727 else:\r
728 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
729 elif Line.startswith(u'"'):\r
730 if u'#string' in Line or u'#language' in Line:\r
731 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
732 NewLines.append(Line)\r
733 else:\r
72443dd2 734 print(Line)\r
421ccda3 735 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, ExtraData=File.Path)\r
f7496d71 736\r
421ccda3
HC
737 if StrName and not StrName.split()[1].startswith(u'STR_'):\r
738 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
739 Message=ST.ERR_UNIPARSE_STRNAME_FORMAT_ERROR % StrName.split()[1], \\r
f7496d71
LG
740 ExtraData=File.Path)\r
741\r
421ccda3
HC
742 if StrName and not NewLines:\r
743 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
744 Message=ST.ERR_UNI_MISS_LANGENTRY % StrName, \\r
745 ExtraData=File.Path)\r
f7496d71 746\r
421ccda3
HC
747 #\r
748 # Check Abstract, Description, BinaryAbstract and BinaryDescription order,\r
749 # should be Abstract, Description, BinaryAbstract, BinaryDesctiption\r
750 AbstractPosition = -1\r
751 DescriptionPosition = -1\r
752 BinaryAbstractPosition = -1\r
753 BinaryDescriptionPosition = -1\r
754 for StrName in ExistStrNameList:\r
755 if DT.TAB_HEADER_ABSTRACT.upper() in StrName:\r
756 if 'BINARY' in StrName:\r
757 BinaryAbstractPosition = ExistStrNameList.index(StrName)\r
758 else:\r
759 AbstractPosition = ExistStrNameList.index(StrName)\r
760 if DT.TAB_HEADER_DESCRIPTION.upper() in StrName:\r
761 if 'BINARY' in StrName:\r
762 BinaryDescriptionPosition = ExistStrNameList.index(StrName)\r
763 else:\r
764 DescriptionPosition = ExistStrNameList.index(StrName)\r
f7496d71 765\r
421ccda3
HC
766 OrderList = sorted([AbstractPosition, DescriptionPosition])\r
767 BinaryOrderList = sorted([BinaryAbstractPosition, BinaryDescriptionPosition])\r
768 Min = OrderList[0]\r
769 Max = OrderList[1]\r
770 BinaryMin = BinaryOrderList[0]\r
771 BinaryMax = BinaryOrderList[1]\r
772 if BinaryDescriptionPosition > -1:\r
773 if not(BinaryDescriptionPosition == BinaryMax and BinaryAbstractPosition == BinaryMin and \\r
774 BinaryMax > Max):\r
775 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
776 Message=ST.ERR_UNIPARSE_ENTRY_ORDER_WRONG, \\r
f7496d71 777 ExtraData=File.Path)\r
421ccda3
HC
778 elif BinaryAbstractPosition > -1:\r
779 if not(BinaryAbstractPosition > Max):\r
780 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
781 Message=ST.ERR_UNIPARSE_ENTRY_ORDER_WRONG, \\r
f7496d71
LG
782 ExtraData=File.Path)\r
783\r
421ccda3
HC
784 if DescriptionPosition > -1:\r
785 if not(DescriptionPosition == Max and AbstractPosition == Min and \\r
786 DescriptionPosition > AbstractPosition):\r
787 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID, \\r
788 Message=ST.ERR_UNIPARSE_ENTRY_ORDER_WRONG, \\r
f7496d71
LG
789 ExtraData=File.Path)\r
790\r
421ccda3 791 if not self.UniFileHeader:\r
f7496d71 792 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID,\r
421ccda3
HC
793 Message = ST.ERR_NO_SOURCE_HEADER,\r
794 ExtraData=File.Path)\r
f7496d71 795\r
421ccda3
HC
796 return NewLines\r
797\r
798 #\r
799 # Load a .uni file\r
800 #\r
801 def LoadUniFile(self, File = None):\r
4231a819 802 if File is None:\r
f7496d71
LG
803 EdkLogger.Error("Unicode File Parser",\r
804 ToolError.PARSER_ERROR,\r
805 Message='No unicode file is given',\r
421ccda3 806 ExtraData=File.Path)\r
f7496d71 807\r
421ccda3 808 self.File = File\r
f7496d71 809\r
421ccda3
HC
810 #\r
811 # Process special char in file\r
812 #\r
813 Lines = self.PreProcess(File)\r
814\r
815 #\r
816 # Get Unicode Information\r
817 #\r
818 for IndexI in range(len(Lines)):\r
819 Line = Lines[IndexI]\r
820 if (IndexI + 1) < len(Lines):\r
821 SecondLine = Lines[IndexI + 1]\r
822 if (IndexI + 2) < len(Lines):\r
823 ThirdLine = Lines[IndexI + 2]\r
824\r
825 #\r
826 # Get Language def information\r
827 #\r
828 if Line.find(u'#langdef ') >= 0:\r
829 self.GetLangDef(File, Line + u' ' + SecondLine)\r
830 continue\r
831\r
832 Name = ''\r
833 Language = ''\r
834 Value = ''\r
835 CombineToken = False\r
836 #\r
837 # Get string def information format as below\r
838 #\r
839 # #string MY_STRING_1\r
840 # #language eng\r
841 # "My first English string line 1"\r
842 # "My first English string line 2"\r
843 # #string MY_STRING_1\r
844 # #language spa\r
845 # "Mi segunda secuencia 1"\r
846 # "Mi segunda secuencia 2"\r
847 #\r
848 if Line.find(u'#string ') >= 0 and Line.find(u'#language ') < 0 and \\r
849 SecondLine.find(u'#string ') < 0 and SecondLine.find(u'#language ') >= 0 and \\r
850 ThirdLine.find(u'#string ') < 0 and ThirdLine.find(u'#language ') < 0:\r
851 if Line.find('"') > 0 or SecondLine.find('"') > 0:\r
f7496d71 852 EdkLogger.Error("Unicode File Parser", ToolError.FORMAT_INVALID,\r
421ccda3
HC
853 Message=ST.ERR_UNIPARSE_DBLQUOTE_UNMATCHED,\r
854 ExtraData=File.Path)\r
f7496d71 855\r
421ccda3
HC
856 Name = Line[Line.find(u'#string ') + len(u'#string ') : ].strip(' ')\r
857 Language = SecondLine[SecondLine.find(u'#language ') + len(u'#language ') : ].strip(' ')\r
858 for IndexJ in range(IndexI + 2, len(Lines)):\r
859 if Lines[IndexJ].find(u'#string ') < 0 and Lines[IndexJ].find(u'#language ') < 0 and \\r
860 Lines[IndexJ].strip().startswith(u'"') and Lines[IndexJ].strip().endswith(u'"'):\r
861 if Lines[IndexJ][-2] == ' ':\r
862 CombineToken = True\r
863 if CombineToken:\r
864 if Lines[IndexJ].strip()[1:-1].strip():\r
865 Value = Value + Lines[IndexJ].strip()[1:-1].rstrip() + ' '\r
866 else:\r
867 Value = Value + Lines[IndexJ].strip()[1:-1]\r
868 CombineToken = False\r
869 else:\r
cf2b2bde 870 Value = Value + Lines[IndexJ].strip()[1:-1] + '\r\n'\r
421ccda3
HC
871 else:\r
872 IndexI = IndexJ\r
873 break\r
cf2b2bde
HC
874 if Value.endswith('\r\n'):\r
875 Value = Value[: Value.rfind('\r\n')]\r
421ccda3
HC
876 Language = GetLanguageCode(Language, self.IsCompatibleMode, self.File)\r
877 self.AddStringToList(Name, Language, Value)\r
878 continue\r
879\r
880 #\r
881 # Load multiple .uni files\r
882 #\r
883 def LoadUniFiles(self, FileList):\r
884 if len(FileList) > 0:\r
885 for File in FileList:\r
886 FilePath = File.Path.strip()\r
887 if FilePath.endswith('.uni') or FilePath.endswith('.UNI') or FilePath.endswith('.Uni'):\r
888 self.LoadUniFile(File)\r
889\r
890 #\r
891 # Add a string to list\r
892 #\r
893 def AddStringToList(self, Name, Language, Value, Token = 0, Referenced = False, UseOtherLangDef = '', Index = -1):\r
894 for LangNameItem in self.LanguageDef:\r
895 if Language == LangNameItem[0]:\r
896 break\r
f7496d71 897\r
421ccda3
HC
898 if Language not in self.OrderedStringList:\r
899 self.OrderedStringList[Language] = []\r
900 self.OrderedStringDict[Language] = {}\r
f7496d71 901\r
421ccda3
HC
902 IsAdded = True\r
903 if Name in self.OrderedStringDict[Language]:\r
904 IsAdded = False\r
4231a819 905 if Value is not None:\r
421ccda3
HC
906 ItemIndexInList = self.OrderedStringDict[Language][Name]\r
907 Item = self.OrderedStringList[Language][ItemIndexInList]\r
908 Item.UpdateValue(Value)\r
f7496d71 909 Item.UseOtherLangDef = ''\r
421ccda3
HC
910\r
911 if IsAdded:\r
912 Token = len(self.OrderedStringList[Language])\r
913 if Index == -1:\r
f7496d71
LG
914 self.OrderedStringList[Language].append(StringDefClassObject(Name,\r
915 Value,\r
916 Referenced,\r
917 Token,\r
421ccda3
HC
918 UseOtherLangDef))\r
919 self.OrderedStringDict[Language][Name] = Token\r
920 for LangName in self.LanguageDef:\r
921 #\r
922 # New STRING token will be added into all language string lists.\r
f7496d71 923 # so that the unique STRING identifier is reserved for all languages in the package list.\r
421ccda3
HC
924 #\r
925 if LangName[0] != Language:\r
926 if UseOtherLangDef != '':\r
927 OtherLangDef = UseOtherLangDef\r
928 else:\r
929 OtherLangDef = Language\r
f7496d71
LG
930 self.OrderedStringList[LangName[0]].append(StringDefClassObject(Name,\r
931 '',\r
932 Referenced,\r
933 Token,\r
421ccda3
HC
934 OtherLangDef))\r
935 self.OrderedStringDict[LangName[0]][Name] = len(self.OrderedStringList[LangName[0]]) - 1\r
936 else:\r
f7496d71
LG
937 self.OrderedStringList[Language].insert(Index, StringDefClassObject(Name,\r
938 Value,\r
939 Referenced,\r
940 Token,\r
421ccda3
HC
941 UseOtherLangDef))\r
942 self.OrderedStringDict[Language][Name] = Index\r
943\r
944 #\r
945 # Set the string as referenced\r
946 #\r
947 def SetStringReferenced(self, Name):\r
948 #\r
949 # String stoken are added in the same order in all language string lists.\r
950 # So, only update the status of string stoken in first language string list.\r
951 #\r
952 Lang = self.LanguageDef[0][0]\r
953 if Name in self.OrderedStringDict[Lang]:\r
954 ItemIndexInList = self.OrderedStringDict[Lang][Name]\r
955 Item = self.OrderedStringList[Lang][ItemIndexInList]\r
956 Item.Referenced = True\r
957\r
958 #\r
959 # Search the string in language definition by Name\r
960 #\r
961 def FindStringValue(self, Name, Lang):\r
962 if Name in self.OrderedStringDict[Lang]:\r
963 ItemIndexInList = self.OrderedStringDict[Lang][Name]\r
964 return self.OrderedStringList[Lang][ItemIndexInList]\r
965\r
966 return None\r
967\r
968 #\r
969 # Search the string in language definition by Token\r
970 #\r
971 def FindByToken(self, Token, Lang):\r
972 for Item in self.OrderedStringList[Lang]:\r
973 if Item.Token == Token:\r
974 return Item\r
975\r
976 return None\r
977\r
978 #\r
979 # Re-order strings and re-generate tokens\r
980 #\r
981 def ReToken(self):\r
982 if len(self.LanguageDef) == 0:\r
983 return None\r
984 #\r
985 # Retoken all language strings according to the status of string stoken in the first language string.\r
986 #\r
987 FirstLangName = self.LanguageDef[0][0]\r
988\r
989 # Convert the OrderedStringList to be OrderedStringListByToken in order to faciliate future search by token\r
990 for LangNameItem in self.LanguageDef:\r
991 self.OrderedStringListByToken[LangNameItem[0]] = {}\r
992\r
993 #\r
994 # Use small token for all referred string stoken.\r
995 #\r
996 RefToken = 0\r
997 for Index in range (0, len (self.OrderedStringList[FirstLangName])):\r
998 FirstLangItem = self.OrderedStringList[FirstLangName][Index]\r
999 if FirstLangItem.Referenced == True:\r
1000 for LangNameItem in self.LanguageDef:\r
1001 LangName = LangNameItem[0]\r
1002 OtherLangItem = self.OrderedStringList[LangName][Index]\r
1003 OtherLangItem.Referenced = True\r
1004 OtherLangItem.Token = RefToken\r
1005 self.OrderedStringListByToken[LangName][OtherLangItem.Token] = OtherLangItem\r
1006 RefToken = RefToken + 1\r
1007\r
1008 #\r
1009 # Use big token for all unreferred string stoken.\r
1010 #\r
1011 UnRefToken = 0\r
1012 for Index in range (0, len (self.OrderedStringList[FirstLangName])):\r
1013 FirstLangItem = self.OrderedStringList[FirstLangName][Index]\r
1014 if FirstLangItem.Referenced == False:\r
1015 for LangNameItem in self.LanguageDef:\r
1016 LangName = LangNameItem[0]\r
1017 OtherLangItem = self.OrderedStringList[LangName][Index]\r
1018 OtherLangItem.Token = RefToken + UnRefToken\r
1019 self.OrderedStringListByToken[LangName][OtherLangItem.Token] = OtherLangItem\r
1020 UnRefToken = UnRefToken + 1\r
1021\r
1022 #\r
1023 # Show the instance itself\r
1024 #\r
1025 def ShowMe(self):\r
72443dd2 1026 print(self.LanguageDef)\r
421ccda3
HC
1027 #print self.OrderedStringList\r
1028 for Item in self.OrderedStringList:\r
72443dd2 1029 print(Item)\r
421ccda3 1030 for Member in self.OrderedStringList[Item]:\r
72443dd2 1031 print(str(Member))\r
f7496d71 1032\r
421ccda3 1033 #\r
f7496d71 1034 # Read content from '!include' UNI file\r
421ccda3
HC
1035 #\r
1036 def ReadIncludeUNIfile(self, FilaPath):\r
1037 if self.File:\r
1038 pass\r
f7496d71 1039\r
421ccda3 1040 if not os.path.exists(FilaPath) or not os.path.isfile(FilaPath):\r
f7496d71 1041 EdkLogger.Error("Unicode File Parser",\r
421ccda3
HC
1042 ToolError.FILE_NOT_FOUND,\r
1043 ExtraData=FilaPath)\r
1044 try:\r
645a5128 1045 FileIn = codecs.open(FilaPath, mode='rb', encoding='utf_8').readlines()\r
5b0671c1 1046 except UnicodeError as Xstr:\r
421ccda3
HC
1047 FileIn = codecs.open(FilaPath, mode='rb', encoding='utf_16').readlines()\r
1048 except UnicodeError:\r
1049 FileIn = codecs.open(FilaPath, mode='rb', encoding='utf_16_le').readlines()\r
1050 except:\r
1051 EdkLogger.Error("Unicode File Parser", ToolError.FILE_OPEN_FAILURE, ExtraData=FilaPath)\r
1052 return FileIn\r
1053\r