Added conditional statement support for !INCLUDE directive
[people/mcb30/basetools.git] / Source / Python / Workspace / MetaFileParser.py
1 ## @file\r
2 # This file is used to create a database used by ECC tool\r
3 #\r
4 # Copyright (c) 2007 ~ 2008, Intel Corporation\r
5 # All rights reserved. This program and the accompanying materials\r
6 # are licensed and made available under the terms and conditions of the BSD License\r
7 # which accompanies this distribution.  The full text of the license may be found at\r
8 # http://opensource.org/licenses/bsd-license.php\r
9 #\r
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12 #\r
13 \r
14 ##\r
15 # Import Modules\r
16 #\r
17 import sqlite3\r
18 import os\r
19 import time\r
20 \r
21 import Common.EdkLogger as EdkLogger\r
22 from CommonDataClass.DataClass import *\r
23 from Common.DataType import *\r
24 from Common.String import *\r
25 from Common.Misc import Blist\r
26 \r
27 class MetaFileParser(object):\r
28     _DataType = {}\r
29     def __init__(self, FilePath, FileType, Table, Macros={}, Owner=-1, From=-1):\r
30         self._Table = Table\r
31         self._FileType = FileType\r
32         self._FilePath = FilePath\r
33         self._FileDir = os.path.dirname(self._FilePath)\r
34         self._Macros = Macros\r
35         # for recursive parsing \r
36         self._Owner = Owner\r
37         self._From = From\r
38 \r
39         # for parsing\r
40         self._Content = None\r
41         self._ValueList = ['', '', '', '', '']\r
42         self._Scope = []\r
43         self._LineIndex = 0\r
44         self._CurrentLine = ''\r
45         self._SectionType = MODEL_UNKNOWN\r
46         self._SectionName = ''\r
47         self._InSubsection = False\r
48         self._SubsectionType = MODEL_UNKNOWN\r
49         self._SubsectionName = ''\r
50         self._LastItem = -1\r
51         self._Enabled = 0\r
52 \r
53     def _Store(self, *Args):\r
54         return self._Table.Insert(*Args)\r
55 \r
56     def Start(self):\r
57         raise NotImplementedError \r
58 \r
59     def _Done(self):\r
60         self._Table.SetEndFlag()\r
61 \r
62     def _CommonParser(self):\r
63         TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)\r
64         self._ValueList[0:len(TokenList)] = TokenList\r
65 \r
66     def _PathParser(self):\r
67         TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT)\r
68         self._ValueList[0:len(TokenList)] = TokenList\r
69         if len(self._Macros) > 0:\r
70             for Index in range(0, len(self._ValueList)):\r
71                 Value = self._ValueList[Index]\r
72                 if Value == None or Value == '':\r
73                     continue\r
74                 self._ValueList[Index] = NormPath(Value, self._Macros)\r
75 \r
76     def _Skip(self):\r
77         self._ValueList[0:1] = [self._CurrentLine]\r
78 \r
79     def _SectionHeaderParser(self):\r
80         self._Scope = []\r
81         for Item in GetSplitValueList(self._CurrentLine[1:-1], TAB_COMMA_SPLIT):\r
82             ItemList = GetSplitValueList(Item, TAB_SPLIT)\r
83             self._SectionName = ItemList[0].upper()\r
84             if self._SectionName in self._DataType:\r
85                 self._SectionType = self._DataType[self._SectionName]\r
86             else:\r
87                 self._SectionType = MODEL_UNKNOWN\r
88             # S1 is always Arch\r
89             if len(ItemList) > 1:\r
90                 S1 = ItemList[1].upper()\r
91             else:\r
92                 S1 = 'COMMON'\r
93             # S2 may be Platform or ModuleType\r
94             if len(ItemList) > 2:\r
95                 S2 = ItemList[2].upper()\r
96             else:\r
97                 S2 = 'COMMON'\r
98             self._Scope.append([S1, S2])\r
99 \r
100     def _DefineParser(self):\r
101         TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
102         self._ValueList[0:len(TokenList)] = TokenList\r
103 \r
104     def _MacroParser(self):\r
105         TokenList = GetSplitValueList(self._CurrentLine, ' ', 1)\r
106         if len(TokenList) <= 1:\r
107             return\r
108         TokenList = GetSplitValueList(TokenList[1], TAB_EQUAL_SPLIT, 1)\r
109         if len(TokenList) < 1:\r
110             return\r
111         if self._Macros == None:\r
112             self._Macros = {}\r
113         self._Macros[TokenList[0]] = TokenList[1]\r
114 \r
115     _SectionParser = {}\r
116 \r
117 class InfParser(MetaFileParser):\r
118     _DataType = {\r
119         TAB_UNKNOWN.upper() : MODEL_UNKNOWN,\r
120         TAB_INF_DEFINES.upper() : MODEL_META_DATA_HEADER,\r
121         TAB_BUILD_OPTIONS.upper() : MODEL_META_DATA_BUILD_OPTION,\r
122         TAB_INCLUDES.upper() : MODEL_EFI_INCLUDE,\r
123         TAB_LIBRARIES.upper() : MODEL_EFI_LIBRARY_INSTANCE,\r
124         TAB_LIBRARY_CLASSES.upper() : MODEL_EFI_LIBRARY_CLASS,\r
125         TAB_PACKAGES.upper() : MODEL_META_DATA_PACKAGE,\r
126         TAB_NMAKE.upper() : MODEL_META_DATA_NMAKE,\r
127         TAB_INF_FIXED_PCD.upper() : MODEL_PCD_FIXED_AT_BUILD,\r
128         TAB_INF_PATCH_PCD.upper() : MODEL_PCD_PATCHABLE_IN_MODULE,\r
129         TAB_INF_FEATURE_PCD.upper() : MODEL_PCD_FEATURE_FLAG,\r
130         TAB_INF_PCD_EX.upper() : MODEL_PCD_DYNAMIC_EX,\r
131         TAB_INF_PCD.upper() : MODEL_PCD_DYNAMIC,\r
132         TAB_SOURCES.upper() : MODEL_EFI_SOURCE_FILE,\r
133         TAB_GUIDS.upper() : MODEL_EFI_GUID,\r
134         TAB_PROTOCOLS.upper() : MODEL_EFI_PROTOCOL,\r
135         TAB_PPIS.upper() : MODEL_EFI_PPI,\r
136         TAB_DEPEX.upper() : MODEL_EFI_DEPEX,\r
137         TAB_BINARIES.upper() : MODEL_EFI_BINARY_FILE,\r
138         TAB_USER_EXTENSIONS.upper() : MODEL_META_DATA_USER_EXTENSION\r
139     }\r
140 \r
141     def __init__(self, FilePath, FileId, FileType, Table, Macros={}):\r
142         MetaFileParser.__init__(self, FilePath, FileType, Table, Macros)\r
143 \r
144     def Start(self):\r
145         try:\r
146             self._Content = open(self._FilePath, 'r').readlines()\r
147         except:\r
148             EdkLogger.error("InfParser", FILE_READ_FAILURE, ExtraData=self._FilePath)\r
149 \r
150         for Index in range(0, len(self._Content)):\r
151             Line = CleanString(self._Content[Index])\r
152             if Line == '':\r
153                 continue\r
154             self._CurrentLine = Line\r
155             self._LineIndex = Index\r
156 \r
157             # section header\r
158             if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:\r
159                 self._SectionHeaderParser()\r
160                 continue\r
161             elif Line.upper().startswith('DEFINE '):\r
162                 self._MacroParser()\r
163                 continue\r
164 \r
165             # section content\r
166             self._ValueList = ['','','']\r
167             self._SectionParser[self._SectionType](self)\r
168 \r
169             # \r
170             # Model, Value1, Value2, Value3, Value4, Value5, Arch, Platform, BelongsToFile=-1, \r
171             # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, BelongsToItem=-1, FeatureFlag='', \r
172             # Enabled=-1\r
173             # \r
174             for Arch, Platform in self._Scope:\r
175                 self._Store(self._SectionType,\r
176                             self._ValueList[0],\r
177                             self._ValueList[1],\r
178                             self._ValueList[2],\r
179                             Arch,\r
180                             Platform,\r
181                             self._Owner,\r
182                             self._LineIndex+1,\r
183                             -1,\r
184                             self._LineIndex+1,\r
185                             -1,\r
186                             0\r
187                             )\r
188         self._Done()\r
189             \r
190     def _BuildOptionParser(self):\r
191         TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
192         TokenList2 = GetSplitValueList(TokenList[0], ':', 1)\r
193         if len(TokenList2) == 2:\r
194             self._ValueList[0] = TokenList2[0]\r
195             self._ValueList[1] = TokenList2[1]\r
196         else:\r
197             self._ValueList[1] = TokenList[0]\r
198         self._ValueList[2] = ReplaceMacro(TokenList[1], self._Macros)\r
199 \r
200     def _NmakeParser(self):\r
201         TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
202         self._ValueList[0:len(TokenList)] = TokenList\r
203         # remove self-reference in macro setting\r
204         self._ValueList[1] = ReplaceMacro(self._ValueList[1], {self._ValueList[0]:''})\r
205 \r
206     def _PcdParser(self):\r
207         TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)\r
208         self._ValueList[0:2] = GetSplitValueList(TokenList[0], TAB_SPLIT)\r
209         if len(TokenList) > 1:\r
210             self._ValueList[2] = TokenList[1]\r
211 \r
212     def _DepexParser(self):\r
213         self._ValueList[0:1] = [self._CurrentLine]\r
214 \r
215     _SectionParser = {\r
216         MODEL_UNKNOWN                   :   MetaFileParser._Skip,\r
217         MODEL_META_DATA_HEADER          :   MetaFileParser._DefineParser,\r
218         MODEL_META_DATA_BUILD_OPTION    :   _BuildOptionParser,\r
219         MODEL_EFI_INCLUDE               :   MetaFileParser._PathParser,     # for R8.x modules\r
220         MODEL_EFI_LIBRARY_INSTANCE      :   MetaFileParser._CommonParser,   # for R8.x modules\r
221         MODEL_EFI_LIBRARY_CLASS         :   MetaFileParser._PathParser,\r
222         MODEL_META_DATA_PACKAGE         :   MetaFileParser._PathParser,\r
223         MODEL_META_DATA_NMAKE           :   _NmakeParser,                   # for R8.x modules\r
224         MODEL_PCD_FIXED_AT_BUILD        :   _PcdParser,\r
225         MODEL_PCD_PATCHABLE_IN_MODULE   :   _PcdParser,\r
226         MODEL_PCD_FEATURE_FLAG          :   _PcdParser,\r
227         MODEL_PCD_DYNAMIC_EX            :   _PcdParser,\r
228         MODEL_PCD_DYNAMIC               :   _PcdParser,\r
229         MODEL_EFI_SOURCE_FILE           :   MetaFileParser._PathParser,\r
230         MODEL_EFI_GUID                  :   MetaFileParser._CommonParser,\r
231         MODEL_EFI_PROTOCOL              :   MetaFileParser._CommonParser,\r
232         MODEL_EFI_PPI                   :   MetaFileParser._CommonParser,\r
233         MODEL_EFI_DEPEX                 :   _DepexParser,\r
234         MODEL_EFI_BINARY_FILE           :   MetaFileParser._PathParser,\r
235         MODEL_META_DATA_USER_EXTENSION  :   MetaFileParser._Skip,\r
236     }    \r
237 \r
238 class DscParser(MetaFileParser):\r
239     _DataType = {\r
240         TAB_SKUIDS.upper()                          :   MODEL_EFI_SKU_ID,\r
241         TAB_LIBRARIES.upper()                       :   MODEL_EFI_LIBRARY_INSTANCE,\r
242         TAB_LIBRARY_CLASSES.upper()                 :   MODEL_EFI_LIBRARY_CLASS,\r
243         TAB_BUILD_OPTIONS.upper()                   :   MODEL_META_DATA_BUILD_OPTION,\r
244         TAB_PCDS_FIXED_AT_BUILD_NULL.upper()        :   MODEL_PCD_FIXED_AT_BUILD,\r
245         TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper()   :   MODEL_PCD_PATCHABLE_IN_MODULE,\r
246         TAB_PCDS_FEATURE_FLAG_NULL.upper()          :   MODEL_PCD_FEATURE_FLAG,\r
247         TAB_PCDS_DYNAMIC_DEFAULT_NULL.upper()       :   MODEL_PCD_DYNAMIC_DEFAULT,\r
248         TAB_PCDS_DYNAMIC_HII_NULL.upper()           :   MODEL_PCD_DYNAMIC_HII,\r
249         TAB_PCDS_DYNAMIC_VPD_NULL.upper()           :   MODEL_PCD_DYNAMIC_VPD,\r
250         TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL.upper()    :   MODEL_PCD_DYNAMIC_EX_DEFAULT,\r
251         TAB_PCDS_DYNAMIC_EX_HII_NULL.upper()        :   MODEL_PCD_DYNAMIC_EX_HII,\r
252         TAB_PCDS_DYNAMIC_EX_VPD_NULL.upper()        :   MODEL_PCD_DYNAMIC_EX_VPD,\r
253         TAB_COMPONENTS.upper()                      :   MODEL_META_DATA_COMPONENT,\r
254         TAB_DSC_DEFINES.upper()                     :   MODEL_META_DATA_HEADER,\r
255         TAB_INCLUDE.upper()                         :   MODEL_META_DATA_INCLUDE,\r
256         TAB_IF.upper()                              :   MODEL_META_DATA_CONDITIONAL_STATEMENT_IF,\r
257         TAB_IF_DEF.upper()                          :   MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF,\r
258         TAB_IF_N_DEF.upper()                        :   MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF,\r
259         TAB_ELSE_IF.upper()                         :   MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF,\r
260         TAB_ELSE.upper()                            :   MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE,\r
261         TAB_END_IF.upper()                          :   MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF,\r
262     }\r
263 \r
264     _IncludeAllowedSection = [\r
265         TAB_LIBRARIES.upper(), \r
266         TAB_LIBRARY_CLASSES.upper(), \r
267         TAB_SKUIDS.upper(),\r
268         TAB_COMPONENTS.upper(),\r
269         TAB_BUILD_OPTIONS.upper(),\r
270         TAB_PCDS_FIXED_AT_BUILD_NULL.upper(),\r
271         TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper(),\r
272         TAB_PCDS_FEATURE_FLAG_NULL.upper(),\r
273         TAB_PCDS_DYNAMIC_DEFAULT_NULL.upper(),\r
274         TAB_PCDS_DYNAMIC_HII_NULL.upper(),\r
275         TAB_PCDS_DYNAMIC_VPD_NULL.upper(),\r
276         TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL.upper(),\r
277         TAB_PCDS_DYNAMIC_EX_HII_NULL.upper(),\r
278         TAB_PCDS_DYNAMIC_EX_VPD_NULL.upper(),\r
279         ]\r
280 \r
281     _OP_ = {\r
282         "!"     :   lambda a:   not a,\r
283         "!="    :   lambda a,b: a!=b,\r
284         "=="    :   lambda a,b: a==b,\r
285         ">"     :   lambda a,b: a>b,\r
286         "<"     :   lambda a,b: a<b,\r
287         "=>"    :   lambda a,b: a>=b,\r
288         ">="    :   lambda a,b: a>=b,\r
289         "<="    :   lambda a,b: a<=b,\r
290         "=<"    :   lambda a,b: a<=b,\r
291     }\r
292 \r
293     def __init__(self, FilePath, FileId, FileType, Table, Macros={}, Owner=-1, From=-1):\r
294         MetaFileParser.__init__(self, FilePath, FileType, Table, Macros, Owner, From)\r
295         # to store conditional directive evaluation result\r
296         self._Eval = Blist()\r
297 \r
298     def Start(self):\r
299         try:\r
300             if self._Content == None:\r
301                 self._Content = open(self._FilePath, 'r').readlines()\r
302         except:\r
303             EdkLogger.error("DscParser", FILE_READ_FAILURE, ExtraData=self._FilePath)\r
304 \r
305         for Index in range(0, len(self._Content)):\r
306             Line = CleanString(self._Content[Index])\r
307             # skip empty line\r
308             if Line == '':\r
309                 self._LineIndex += 1\r
310                 continue\r
311             self._CurrentLine = Line\r
312             self._LineIndex = Index\r
313 \r
314             # section header\r
315             if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:\r
316                 self._SectionHeaderParser()\r
317                 continue\r
318             elif Line[0] == '}':\r
319                 self._InSubsection = False\r
320                 self._Owner = -1\r
321                 continue\r
322             elif Line[0] == TAB_OPTION_START and Line[-1] == TAB_OPTION_END:\r
323                 self._SubsectionHeaderParser()\r
324                 continue\r
325             # directive line\r
326             elif Line[0] == '!':\r
327                 self._DirectiveParser()\r
328                 continue\r
329             elif Line.upper().startswith('DEFINE '):\r
330                 self._MacroParser()\r
331                 continue\r
332 \r
333             # section content\r
334             if self._InSubsection:\r
335                 SectionType = self._SubsectionType\r
336                 SectionName = self._SubsectionName\r
337                 if self._Owner == -1:\r
338                     self._Owner = self._LastItem\r
339             else:\r
340                 SectionType = self._SectionType\r
341                 SectionName = self._SectionName\r
342             self._ValueList = ['','','']\r
343             self._SectionParser[SectionType](self)\r
344             EdkLogger.debug(EdkLogger.DEBUG_8, "Define: %s" % self._ValueList)\r
345             if self._ValueList == None:\r
346                 continue\r
347 \r
348             # \r
349             # Model, Value1, Value2, Value3, Arch, Platform, BelongsToFile=-1, \r
350             # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, BelongsToItem=-1, \r
351             # Enabled=-1\r
352             # \r
353             for Arch, ModuleType in self._Scope:\r
354                 self._LastItem = self._Store(\r
355                     SectionType,\r
356                     self._ValueList[0],\r
357                     self._ValueList[1],\r
358                     self._ValueList[2],\r
359                     Arch,\r
360                     ModuleType,\r
361                     self._Owner,\r
362                     self._From,\r
363                     self._LineIndex+1,\r
364                     -1,\r
365                     self._LineIndex+1,\r
366                     -1,\r
367                     self._Enabled\r
368                     )\r
369         self._Done()\r
370 \r
371     def _DefineParser(self):\r
372         TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
373         if len(TokenList) > 1:\r
374             if TokenList[0] in ['FLASH_DEFINITION', 'OUTPUT_DIRECTORY']:\r
375                 TokenList[1] = NormPath(TokenList[1], self._Macros)\r
376         self._ValueList[0:len(TokenList)] = TokenList\r
377     \r
378             \r
379     def _SubsectionHeaderParser(self):\r
380         self._SubsectionName = self._CurrentLine[1:-1].upper()\r
381         if self._SubsectionName in self._DataType:\r
382             self._SubsectionType = self._DataType[self._SubsectionName]\r
383         else:\r
384             self._SubsectionType = MODEL_UNKNOWN\r
385 \r
386     def _DirectiveParser(self):\r
387         self._ValueList = ['','','']\r
388         TokenList = GetSplitValueList(self._CurrentLine, ' ', 1)\r
389         self._ValueList[0:len(TokenList)] = TokenList\r
390         DirectiveName = self._ValueList[0].upper()\r
391         self._LastItem = self._Store(\r
392             self._DataType[DirectiveName],\r
393             self._ValueList[0],\r
394             self._ValueList[1],\r
395             self._ValueList[2],\r
396             'COMMON',\r
397             'COMMON',\r
398             self._Owner,\r
399             self._LineIndex + 1,\r
400             -1,\r
401             self._LineIndex + 1,\r
402             -1,\r
403             0\r
404             )\r
405         if DirectiveName == "!INCLUDE":\r
406             if not self._SectionName in self._IncludeAllowedSection:\r
407                 EdkLogger.error("DscParser", FORMAT_INVALID, File=self._FilePath, Line=self._LineIndex+1,\r
408                                 ExtraData="'!include' is not allowed in section %s" % self._SectionName)\r
409             # the included file must be relative to the parsing file\r
410             IncludedFile = os.path.join(self._FileDir, self._ValueList[1])\r
411             Parser = DscParser(IncludedFile, self._FileType, self._Table, self._Macros, From=self._LastItem)\r
412             Parser._SectionName = self._SectionName\r
413             Parser._SectionType = self._SectionType\r
414             Parser._Scope = self._Scope\r
415             Parser._Enabled = self._Enabled\r
416             try:\r
417                 Parser.Start()\r
418             except:\r
419                 EdkLogger.error("DscParser", PARSER_ERROR, File=self._FilePath, Line=self._LineIndex+1,\r
420                                 ExtraData="Failed to parse content in file %s" % IncludedFile)\r
421             self._SectionName = Parser._SectionName\r
422             self._SectionType = Parser._SectionType\r
423             self._Scope       = Parser._Scope\r
424             self._Enabled     = Parser._Enabled\r
425         else:\r
426             if DirectiveName in ["!IF", "!IFDEF", "!IFNDEF"]:\r
427                 # evaluate the expression\r
428                 Result = self._Evaluate(self._ValueList[1])\r
429                 if DirectiveName == "!IFNDEF":\r
430                     Result = not Result\r
431                 self._Eval.append(Result)\r
432             elif DirectiveName in ["!ELSEIF"]:\r
433                 # evaluate the expression\r
434                 self._Eval[-1] = (not self._Eval[-1]) & self._Evaluate(self._ValueList[1])\r
435             elif DirectiveName in ["!ELSE"]:\r
436                 self._Eval[-1] = not self._Eval[-1]\r
437             elif DirectiveName in ["!ENDIF"]:\r
438                 if len(self._Eval) > 0:\r
439                     self._Eval.pop()\r
440                 else:\r
441                     EdkLogger.error("DscParser", FORMAT_INVALID, "!IF..[!ELSE]..!ENDIF doesn't match",\r
442                                     File=self._FilePath, Line=self._LineIndex+1)\r
443             if self._Eval.Result == False:\r
444                 self._Enabled = 0 - len(self._Eval)\r
445             else:\r
446                 self._Enabled = len(self._Eval)\r
447 \r
448     def _Evaluate(self, Expression):\r
449         TokenList = Expression.split()\r
450         TokenNumber = len(TokenList)\r
451         if TokenNumber == 1:\r
452             return TokenList[0] in self._Macros\r
453         elif TokenNumber == 2:\r
454             Op = TokenList[0]\r
455             if Op not in self._OP_:\r
456                 EdkLogger.error('DscParser', FORMAT_INVALID, File=self._FilePath, \r
457                                 Line=self._LineIndex+1, ExtraData=Expression)\r
458             if TokenList[1].upper() == 'TRUE':\r
459                 Value = True\r
460             else:\r
461                 Value = False\r
462             return self._OP_[Op](Value)\r
463         elif TokenNumber == 3:\r
464             Name = TokenList[0]\r
465             if Name not in self._Macros:\r
466                 return False\r
467             Value = TokenList[2]\r
468             if Value[0] in ["'", '"']:\r
469                 Value = Value[1:-1]\r
470             Op = TokenList[1]\r
471             return self._OP_[Op](self._Macros[Macro], Value)\r
472         else:\r
473             EdkLogger.error('DscParser', FORMAT_INVALID, File=self._FilePath, Line=self._LineIndex+1,\r
474                             ExtraData=Expression)\r
475 \r
476     def _BuildOptionParser(self):\r
477         TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
478         TokenList2 = GetSplitValueList(TokenList[0], ':', 1)\r
479         if len(TokenList2) == 2:\r
480             self._ValueList[0] = TokenList2[0]\r
481             self._ValueList[1] = TokenList2[1]\r
482         else:\r
483             self._ValueList[1] = TokenList[0]\r
484         self._ValueList[2] = ReplaceMacro(TokenList[1], self._Macros)\r
485 \r
486     def _PcdParser(self):\r
487         TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)\r
488         self._ValueList[0:2] = GetSplitValueList(TokenList[0], TAB_SPLIT)\r
489         self._ValueList[2] = TokenList[1]\r
490 \r
491     def _ComponentParser(self):        \r
492         if self._CurrentLine[-1] == '{':\r
493             self._InSubsection = True\r
494             self._ValueList[0] = self._CurrentLine[0:-1].strip()\r
495         else:\r
496             self._ValueList[0] = self._CurrentLine\r
497         if len(self._Macros) > 0:\r
498             self._ValueList[0] = NormPath(self._ValueList[0], self._Macros)\r
499 \r
500     _SectionParser = {\r
501         MODEL_META_DATA_HEADER          :   MetaFileParser._DefineParser,\r
502         MODEL_EFI_SKU_ID                :   MetaFileParser._CommonParser,\r
503         MODEL_EFI_LIBRARY_INSTANCE      :   MetaFileParser._PathParser,\r
504         MODEL_EFI_LIBRARY_CLASS         :   MetaFileParser._PathParser,\r
505         MODEL_PCD_FIXED_AT_BUILD        :   _PcdParser,\r
506         MODEL_PCD_PATCHABLE_IN_MODULE   :   _PcdParser,\r
507         MODEL_PCD_FEATURE_FLAG          :   _PcdParser,\r
508         MODEL_PCD_DYNAMIC_DEFAULT       :   _PcdParser,\r
509         MODEL_PCD_DYNAMIC_HII           :   _PcdParser,\r
510         MODEL_PCD_DYNAMIC_VPD           :   _PcdParser,\r
511         MODEL_PCD_DYNAMIC_EX_DEFAULT    :   _PcdParser,\r
512         MODEL_PCD_DYNAMIC_EX_HII        :   _PcdParser,\r
513         MODEL_PCD_DYNAMIC_EX_VPD        :   _PcdParser,\r
514         MODEL_META_DATA_COMPONENT       :   _ComponentParser,\r
515         MODEL_META_DATA_BUILD_OPTION    :   _BuildOptionParser,\r
516         MODEL_UNKNOWN                   :   MetaFileParser._Skip,\r
517         MODEL_META_DATA_USER_EXTENSION  :   MetaFileParser._Skip,\r
518     }\r
519 \r
520 class DecParser(MetaFileParser):\r
521     _DataType = {\r
522         TAB_DEC_DEFINES.upper()                     :   MODEL_META_DATA_HEADER,\r
523         TAB_INCLUDES.upper()                        :   MODEL_EFI_INCLUDE,\r
524         TAB_LIBRARY_CLASSES.upper()                 :   MODEL_EFI_LIBRARY_CLASS,\r
525         TAB_GUIDS.upper()                           :   MODEL_EFI_GUID,\r
526         TAB_PPIS.upper()                            :   MODEL_EFI_PPI,\r
527         TAB_PROTOCOLS.upper()                       :   MODEL_EFI_PROTOCOL,\r
528         TAB_PCDS_FIXED_AT_BUILD_NULL.upper()        :   MODEL_PCD_FIXED_AT_BUILD,\r
529         TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper()   :   MODEL_PCD_PATCHABLE_IN_MODULE,\r
530         TAB_PCDS_FEATURE_FLAG_NULL.upper()          :   MODEL_PCD_FEATURE_FLAG,\r
531         TAB_PCDS_DYNAMIC_NULL.upper()               :   MODEL_PCD_DYNAMIC,\r
532         TAB_PCDS_DYNAMIC_EX_NULL.upper()            :   MODEL_PCD_DYNAMIC_EX,\r
533     }\r
534 \r
535     def __init__(self, FilePath, FileId, FileType, Table, Macro={}):\r
536         MetaFileParser.__init__(self, FilePath, FileType, Table, Macro, -1)\r
537 \r
538     def Start(self):\r
539         try:\r
540             if self._Content == None:\r
541                 self._Content = open(self._FilePath, 'r').readlines()\r
542         except:\r
543             EdkLogger.error("DecParser", FILE_READ_FAILURE, ExtraData=self._FilePath)\r
544 \r
545         for Index in range(0, len(self._Content)):\r
546             Line = CleanString(self._Content[Index])\r
547             # skip empty line\r
548             if Line == '':\r
549                 continue\r
550             self._CurrentLine = Line\r
551             self._LineIndex = Index\r
552 \r
553             # section header\r
554             if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:\r
555                 self._SectionHeaderParser()\r
556                 continue\r
557             elif Line.startswith('DEFINE '):\r
558                 self._MacroParser()\r
559                 continue\r
560 \r
561             # section content\r
562             self._ValueList = ['','','']\r
563             self._SectionParser[self._SectionType](self)\r
564             EdkLogger.debug(EdkLogger.DEBUG_8, "Define: %s" % self._ValueList)\r
565             if self._ValueList == None:\r
566                 continue\r
567 \r
568             # \r
569             # Model, Value1, Value2, Value3, Value4, Value5, Arch, Platform, BelongsToFile=-1, \r
570             # LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, BelongsToItem=-1, FeatureFlag='', \r
571             # Enabled=-1\r
572             # \r
573             for Arch, ModuleType in self._Scope:\r
574                 self._LastItem = self._Store(\r
575                     self._SectionType,\r
576                     self._ValueList[0],\r
577                     self._ValueList[1],\r
578                     self._ValueList[2],\r
579                     Arch,\r
580                     ModuleType,\r
581                     self._Owner,\r
582                     self._LineIndex+1,\r
583                     -1,\r
584                     self._LineIndex+1,\r
585                     -1,\r
586                     0\r
587                     )\r
588         self._Done()\r
589             \r
590     #def _DefineParser(self):\r
591     #    TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
592     #    self._ValueList[0] = TokenList[0]\r
593     #    if len(TokenList) == 2:\r
594     #        MoreValues = GetSplitValueList(TokenList[1], TAB_VALUE_SPLIT)\r
595     #        self._ValueList[1:1+len(MoreValues)] = MoreValues\r
596 \r
597     def _GuidParser(self):\r
598         TokenList = GetSplitValueList(self._CurrentLine, TAB_EQUAL_SPLIT, 1)\r
599         self._ValueList[0] = TokenList[0]\r
600         self._ValueList[1] = TokenList[1]\r
601 \r
602     def _PcdParser(self):\r
603         TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)\r
604         self._ValueList[0:2] = GetSplitValueList(TokenList[0], TAB_SPLIT)\r
605         self._ValueList[2] = TokenList[1]\r
606 \r
607     _SectionParser = {\r
608         MODEL_META_DATA_HEADER          :   MetaFileParser._DefineParser,\r
609         MODEL_EFI_INCLUDE               :   MetaFileParser._PathParser,\r
610         MODEL_EFI_LIBRARY_CLASS         :   MetaFileParser._PathParser,\r
611         MODEL_EFI_GUID                  :   _GuidParser,\r
612         MODEL_EFI_PPI                   :   _GuidParser,\r
613         MODEL_EFI_PROTOCOL              :   _GuidParser,\r
614         MODEL_PCD_FIXED_AT_BUILD        :   _PcdParser,\r
615         MODEL_PCD_PATCHABLE_IN_MODULE   :   _PcdParser,\r
616         MODEL_PCD_FEATURE_FLAG          :   _PcdParser,\r
617         MODEL_PCD_DYNAMIC               :   _PcdParser,\r
618         MODEL_PCD_DYNAMIC_EX            :   _PcdParser,\r
619         MODEL_UNKNOWN                   :   MetaFileParser._Skip,\r
620         MODEL_META_DATA_USER_EXTENSION  :   MetaFileParser._Skip,\r
621     }\r
622 \r
623 class Timer(object):\r
624     def __init__(self):\r
625         self.StartTime = 0\r
626         self.EndTime = 0\r
627 \r
628     def __str__(self):\r
629         if self.EndTime != 0:\r
630             return str(self.EndTime - self.StartTime)\r
631         return time.clock() - self.StartTime\r
632 \r
633     def Start(self):\r
634         self.StartTime = time.clock()\r
635 \r
636     def Stop(self):\r
637         self.EndTime = time.clock()\r
638 \r
639 ##\r
640 #\r
641 # This acts like the main() function for the script, unless it is 'import'ed into another\r
642 # script.\r
643 #\r
644 if __name__ == '__main__':\r
645     from WorkspaceDatabase import WorkspaceDatabase as DB\r
646 \r
647     try:\r
648         import psyco\r
649         #psyco.profile()\r
650         #psyco.log()\r
651     except:\r
652         pass\r
653     timer = Timer()\r
654     timer.Start()\r
655 \r
656     EdkLogger.Initialize()\r
657     if os.path.exists("test.db"):\r
658         os.remove("test.db")\r
659     Wks = DB("test.db")\r
660     Wks.InitDatabase()\r
661 \r
662     os.chdir(r"H:\dev\AllPackagesDev")\r
663 \r
664     #Gf = r"H:\dev\AllPackagesDev\LakeportX64Pkg\LakeportX64Pkg.dec"\r
665     ##Gf = r"H:\dev\AllPackagesDev\Nt32Pkg\Nt32Pkg.dec"\r
666     #Gb32 = Wks.BuildObject[Gf, MODEL_FILE_DEC, 'IA32']\r
667     #print repr(Gb32)\r
668 \r
669     Pf = r"H:\dev\AllPackagesDev\LakeportX64Pkg\LakeportX64Pkg.dsc"\r
670     #Pf = r"H:\dev\AllPackagesDev\Nt32Pkg\Nt32Pkg.dsc"\r
671     Pb32 = Wks.BuildObject[Pf, MODEL_FILE_DSC, 'IA32']\r
672 \r
673     print repr(Pb32)\r
674     for Mb in Pb32.Modules:\r
675         print repr(Mb)\r
676 \r
677     Pb64 = Wks.BuildObject[Pf, MODEL_FILE_DSC, 'X64']\r
678 \r
679     print repr(Pb64)\r
680     for Mb in Pb64.Modules:\r
681         print repr(Mb)\r
682 \r
683     #LibList = []\r
684     #for Key in Pb32.LibraryClasses:\r
685     #    Inf = Pb32.LibraryClasses[Key]\r
686     #    if Inf  in LibList:\r
687     #        continue \r
688     #    Wks[Inf] = MODEL_FILE_INF\r
689     #    Mb = Module(Inf, Wks[Inf], 'IA32')\r
690     #    print repr(Mb)\r
691     #    LibList.append(Inf)\r
692     #\r
693     #Pb64 = Platform(Pf, Dsc, 'X64')\r
694     #print repr(Pb64)\r
695     #for Inf in Pb64.Modules:\r
696     #    Wks[Inf] = MODEL_FILE_INF\r
697     #    Mb = Module(Inf, Wks[Inf], 'X64')\r
698     #    print repr(Mb)\r
699     #LibList = []\r
700     #for Key in Pb64.LibraryClasses:\r
701     #    Inf = Pb64.LibraryClasses[Key]\r
702     #    if Inf in LibList:\r
703     #        continue \r
704     #    Wks[Inf] = MODEL_FILE_INF\r
705     #    Mb = Module(Inf, Wks[Inf], 'X64')\r
706     #    print repr(Mb)\r
707     #    LibList.append(Inf)\r
708 \r
709     Wks.Close()\r
710     timer.Stop()\r
711     print "DONE [%s]" % str(timer)\r