Changed the uses of EdkLogger
[people/mcb30/basetools.git] / Source / Python / AutoGen / UniClassObject.py
1 # Copyright (c) 2007, Intel Corporation\r
2 # All rights reserved. This program and the accompanying materials\r
3 # are licensed and made available under the terms and conditions of the BSD License\r
4 # which accompanies this distribution.  The full text of the license may be found at\r
5 # http://opensource.org/licenses/bsd-license.php\r
6 #\r
7 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
8 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
9 \r
10 #\r
11 #This file is used to collect all defined strings in multiple uni files\r
12 #\r
13 \r
14 import os, codecs, re\r
15 import Common.EdkLogger\r
16 from Common.BuildToolError import *\r
17 \r
18 UNICODE_WIDE_CHAR = u'\\wide'\r
19 UNICODE_NARROW_CHAR = u'\\narrow'\r
20 UNICODE_NON_BREAKING_CHAR = u'\\nbr'\r
21 UNICODE_UNICODE_CR = '\r'\r
22 UNICODE_UNICODE_LF = '\n'\r
23 \r
24 NARROW_CHAR = u'\uFFF0'\r
25 WIDE_CHAR = u'\uFFF1'\r
26 NON_BREAKING_CHAR = u'\uFFF2'\r
27 CR = u'\u000D'\r
28 LF = u'\u000A'\r
29 NULL = u'\u0000'\r
30 TAB = u'\t'\r
31 BACK_SPLASH = u'\\'\r
32 \r
33 gIncludePattern = re.compile("^#include +[\"<]+([^\"< >]+)[>\"]+$", re.MULTILINE | re.UNICODE)\r
34 \r
35 def UniToStr(Uni):\r
36     return repr(Uni)[2:-1]\r
37 \r
38 def UniToHexList(Uni):\r
39     List = []\r
40     for Item in Uni:\r
41         Temp = '%04X' % ord(Item)\r
42         List.append('0x' + Temp[2:4])\r
43         List.append('0x' + Temp[0:2])\r
44     return List\r
45 \r
46 class StringDefClassObject(object):\r
47     def __init__(self, Name = None, Value = None, Referenced = False, Token = None, UseOtherLangDef = ''):\r
48         self.StringName = ''\r
49         self.StringNameByteList = []\r
50         self.StringValue = ''\r
51         self.StringValueByteList = ''\r
52         self.Token = 0\r
53         self.Referenced = Referenced\r
54         self.UseOtherLangDef = UseOtherLangDef\r
55         self.Length = 0\r
56 \r
57         if Name != None:\r
58             self.StringName = Name\r
59             self.StringNameByteList = UniToHexList(Name)\r
60         if Value != None:\r
61             self.StringValue = Value + u'\x00'        # Add a NULL at string tail\r
62             self.StringValueByteList = UniToHexList(self.StringValue)\r
63             self.Length = len(self.StringValueByteList)\r
64         if Token != None:\r
65             self.Token = Token\r
66 \r
67     def __str__(self):\r
68         return repr(self.StringName) + ' ' + \\r
69                repr(self.Token) + ' ' + \\r
70                repr(self.Referenced) + ' ' + \\r
71                repr(self.StringValue)\r
72 \r
73 class UniFileClassObject(object):\r
74     def __init__(self, FileList = []):\r
75         self.FileList = FileList\r
76         self.Token = 2\r
77         self.LanguageDef = []                   #[ [u'LanguageIdentifier', u'PrintableName'], ... ]\r
78         self.OrderedStringList = {}             #{ u'LanguageIdentifier' : [StringDefClassObject]  }\r
79 \r
80         if len(self.FileList) > 0:\r
81             self.LoadUniFiles(FileList)\r
82 \r
83     def GetLangDef(self, Line):\r
84         Lang = Line.split()\r
85         if len(Lang) != 3:\r
86             EdkLogger.error("Unicode File Parser", PARSER_ERROR, "Wrong language definition",\r
87                             ExtraData="""%s\n\t*Correct format is '#langdef eng "English"'""" % Line)\r
88         else:\r
89             LangName = Lang[1]\r
90             LangPrintName = Lang[2][1:-1]\r
91 \r
92         if [LangName, LangPrintName] not in self.LanguageDef:\r
93             self.LanguageDef.append([LangName, LangPrintName])\r
94 \r
95         #\r
96         # Add language string\r
97         #\r
98         self.AddStringToList(u'$LANGUAGE_NAME', LangName, LangName, 0, True)\r
99         self.AddStringToList(u'$PRINTABLE_LANGUAGE_NAME', LangName, LangPrintName, 1, True)\r
100 \r
101         return True\r
102 \r
103     def GetStringObject(self, Item):\r
104         Name = ''\r
105         Language = ''\r
106         Value = ''\r
107 \r
108         Name = Item.split()[1]\r
109         LanguageList = Item.split(u'#language ')\r
110         for IndexI in range(len(LanguageList)):\r
111             if IndexI == 0:\r
112                 continue\r
113             else:\r
114                 Language = LanguageList[IndexI].split()[0]\r
115                 Value = LanguageList[IndexI][LanguageList[IndexI].find(u'\"') + len(u'\"') : LanguageList[IndexI].rfind(u'\"')].replace(u'\r\n', u'')\r
116                 self.AddStringToList(Name, Language, Value)\r
117 \r
118     def GetIncludeFile(self, Item, Dir):\r
119         FileName = Item[Item.find(u'#include ') + len(u'#include ') :Item.find(u' ', len(u'#include '))][1:-1]\r
120         self.LoadUniFile(FileName)\r
121 \r
122     def PreProcess(self, File):\r
123         if not os.path.exists(File) or not os.path.isfile(File):\r
124             EdkLogger.error("Unicode File Parser", FILE_NOT_FOUND, ExtraData=File)\r
125 \r
126         Dir = os.path.dirname(File)\r
127         FileIn = codecs.open(File, mode='rb', encoding='utf-16').readlines()\r
128         Lines = []\r
129         #\r
130         # Use unique identifier\r
131         #\r
132         for Line in FileIn:\r
133             Line = Line.strip()\r
134             #\r
135             # Ignore comment line and empty line\r
136             #\r
137             if Line == u'' or Line.startswith(u'//'):\r
138                 continue\r
139             Line = Line.replace(u'/langdef', u'#langdef')\r
140             Line = Line.replace(u'/string', u'#string')\r
141             Line = Line.replace(u'/language', u'#language')\r
142             Line = Line.replace(u'/include', u'#include')\r
143 \r
144             Line = Line.replace(UNICODE_WIDE_CHAR, WIDE_CHAR)\r
145             Line = Line.replace(UNICODE_NARROW_CHAR, NARROW_CHAR)\r
146             Line = Line.replace(UNICODE_NON_BREAKING_CHAR, NON_BREAKING_CHAR)\r
147             Line = Line.replace(u'\\r\\n', CR + LF)\r
148             Line = Line.replace(u'\\n', CR + LF)\r
149             Line = Line.replace(u'\\r', CR)\r
150             Line = Line.replace(u'\\t', u'\t')\r
151             Line = Line.replace(u'\\\\', u'\\')\r
152             Line = Line.replace(u'''\"''', u'''"''')\r
153             Line = Line.replace(u'\t', u' ')\r
154 #           if Line.find(u'\\x'):\r
155 #               hex = Line[Line.find(u'\\x') + 2 : Line.find(u'\\x') + 6]\r
156 #               hex = "u'\\u" + hex + "'"\r
157 \r
158             IncList = gIncludePattern.findall(Line)\r
159             if len(IncList) == 1:\r
160                 Lines.extend(self.PreProcess(os.path.join(Dir, IncList[0])))\r
161                 continue\r
162 \r
163             Lines.append(Line)\r
164 \r
165         return Lines\r
166 \r
167     def LoadUniFile(self, File = None):\r
168         if File == None:\r
169             EdkLogger.error("Unicode File Parser", PARSER_ERROR, 'No unicode file is given')\r
170         #\r
171         # Process special char in file\r
172         #\r
173         Lines = self.PreProcess(File)\r
174 \r
175         #\r
176         # Get Unicode Information\r
177         #\r
178         for IndexI in range(len(Lines)):\r
179             Line = Lines[IndexI]\r
180             if (IndexI + 1) < len(Lines):\r
181                 SecondLine = Lines[IndexI + 1]\r
182             if (IndexI + 2) < len(Lines):\r
183                 ThirdLine = Lines[IndexI + 2]\r
184 \r
185             #\r
186             # Get Language def information\r
187             #\r
188             if Line.find(u'#langdef ') >= 0:\r
189                 self.GetLangDef(Line)\r
190                 continue\r
191 \r
192             Name = ''\r
193             Language = ''\r
194             Value = ''\r
195             #\r
196             # Get string def information format 1 as below\r
197             #\r
198             #     #string MY_STRING_1\r
199             #     #language eng\r
200             #     My first English string line 1\r
201             #     My first English string line 2\r
202             #     #string MY_STRING_1\r
203             #     #language spa\r
204             #     Mi segunda secuencia 1\r
205             #     Mi segunda secuencia 2\r
206             #\r
207             if Line.find(u'#string ') >= 0 and Line.find(u'#language ') < 0 and \\r
208                 SecondLine.find(u'#string ') < 0 and SecondLine.find(u'#language ') >= 0 and \\r
209                 ThirdLine.find(u'#string ') < 0 and ThirdLine.find(u'#language ') < 0:\r
210                 Name = Line[Line.find(u'#string ') + len(u'#string ') : ].strip()\r
211                 Language = SecondLine[SecondLine.find(u'#language ') + len(u'#language ') : ].strip()\r
212                 for IndexJ in range(IndexI + 2, len(Lines)):\r
213                     if Lines[IndexJ].find(u'#string ') < 0 and Lines[IndexJ].find(u'#language ') < 0:\r
214                         Value = Value + Lines[IndexJ]\r
215                     else:\r
216                         IndexI = IndexJ\r
217                         break\r
218                 Value = Value.replace(u'\r\n', u'')\r
219                 self.AddStringToList(Name, Language, Value)\r
220                 continue\r
221 \r
222             #\r
223             # Get string def information format 2 as below\r
224             #\r
225             #     #string MY_STRING_1     #language eng     "My first English string line 1"\r
226             #                                               "My first English string line 2"\r
227             #                             #language spa     "Mi segunda secuencia 1"\r
228             #                                               "Mi segunda secuencia 2"\r
229             #     #string MY_STRING_2     #language eng     "My first English string line 1"\r
230             #                                               "My first English string line 2"\r
231             #     #string MY_STRING_2     #language spa     "Mi segunda secuencia 1"\r
232             #                                               "Mi segunda secuencia 2"\r
233             #\r
234             if Line.find(u'#string ') >= 0 and Line.find(u'#language ') >= 0:\r
235                 StringItem = Line\r
236                 for IndexJ in range(IndexI + 1, len(Lines)):\r
237                     if Lines[IndexJ].find(u'#string ') >= 0 and Lines[IndexJ].find(u'#language ') >= 0:\r
238                         IndexI = IndexJ\r
239                         break\r
240                     elif Lines[IndexJ].find(u'#string ') < 0 and Lines[IndexJ].find(u'#language ') >= 0:\r
241                         StringItem = StringItem + Lines[IndexJ]\r
242                     elif Lines[IndexJ].find(u'\"') >= 2:\r
243                         StringItem = StringItem[ : StringItem.rfind(u'\"')] + Lines[IndexJ][Lines[IndexJ].find(u'\"') + len(u'\"') : ]\r
244                 self.GetStringObject(StringItem)\r
245 \r
246     def LoadUniFiles(self, FileList = []):\r
247         if len(FileList) > 0:\r
248             for File in FileList:\r
249                 self.LoadUniFile(File)\r
250 \r
251     def AddStringToList(self, Name, Language, Value, Token = None, Referenced = False, UseOtherLangDef = '', Index = -1):\r
252         if Language not in self.OrderedStringList:\r
253             self.OrderedStringList[Language] = []\r
254 \r
255         IsAdded = False\r
256         for Item in self.OrderedStringList[Language]:\r
257             if Name == Item.StringName:\r
258                 IsAdded = True\r
259                 break\r
260         if not IsAdded:\r
261             Token = len(self.OrderedStringList[Language])\r
262             if Index == -1:\r
263                 self.OrderedStringList[Language].append(StringDefClassObject(Name, Value, Referenced, Token, UseOtherLangDef))\r
264             else:\r
265                 self.OrderedStringList[Language].insert(Index, StringDefClassObject(Name, Value, Referenced, Token, UseOtherLangDef))\r
266 \r
267     def SetStringReferenced(self, Name):\r
268         for Lang in self.OrderedStringList:\r
269             for Item in self.OrderedStringList[Lang]:\r
270                 if Name == Item.StringName:\r
271                     Item.Referenced = True\r
272                     break\r
273 \r
274     def FindStringValue(self, Name, Lang):\r
275         for Item in self.OrderedStringList[Lang]:\r
276             if Item.StringName == Name:\r
277                 return Item\r
278 \r
279         return None\r
280 \r
281     def ReToken(self):\r
282         #\r
283         # Search each string to find if it is defined for each language\r
284         # Use secondary language value to replace if missing in any one language\r
285         #\r
286         for IndexI in range(0, len(self.LanguageDef)):\r
287             LangKey = self.LanguageDef[IndexI][0]\r
288             for Item in self.OrderedStringList[LangKey]:\r
289                 Name = Item.StringName\r
290                 Value = Item.StringValue[0:-1]\r
291                 Referenced = Item.Referenced\r
292                 Index = self.OrderedStringList[LangKey].index(Item)\r
293                 for IndexJ in range(0, len(self.LanguageDef)):\r
294                     LangFind = self.LanguageDef[IndexJ][0]\r
295                     if self.FindStringValue(Name, LangFind) == None:\r
296                         Token = len(self.OrderedStringList[LangFind])\r
297                         self.AddStringToList(Name, LangFind, Value, Token, Referenced, LangKey, Index)\r
298 \r
299         #\r
300         # Retoken\r
301         #\r
302         for Lang in self.LanguageDef:\r
303             LangName = Lang[0]\r
304             ReferencedStringList = []\r
305             NotReferencedStringList = []\r
306             Token = 0\r
307             for Item in self.OrderedStringList[LangName]:\r
308                 if Item.Referenced == True:\r
309                     Item.Token = Token\r
310                     ReferencedStringList.append(Item)\r
311                     Token = Token + 1\r
312                 else:\r
313                     NotReferencedStringList.append(Item)\r
314             self.OrderedStringList[LangName] = ReferencedStringList\r
315             for Index in range(len(NotReferencedStringList)):\r
316                 NotReferencedStringList[Index].Token = Token + Index\r
317                 self.OrderedStringList[LangName].append(NotReferencedStringList[Index])\r
318 \r
319     def ShowMe(self):\r
320         print self.LanguageDef\r
321         #print self.OrderedStringList\r
322         for Item in self.OrderedStringList:\r
323             print Item\r
324             for Member in self.OrderedStringList[Item]:\r
325                 print str(Member)\r
326 \r
327 # This acts like the main() function for the script, unless it is 'import'ed into another\r
328 # script.\r
329 if __name__ == '__main__':\r
330     a = UniFileClassObject(['C:\\Tiano\\Edk\\Sample\\Universal\\UserInterface\\SetupBrowser\\Dxe\\DriverSample\\inventorystrings.uni', 'C:\\Tiano\\Edk\\Sample\\Universal\\UserInterface\\SetupBrowser\\Dxe\\DriverSample\\VfrStrings.uni'])\r
331     a.ShowMe()\r