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