]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Common/Parsing.py
Sync BaseTool trunk (version r2670) into EDKII BaseTools.
[mirror_edk2.git] / BaseTools / Source / Python / Common / Parsing.py
CommitLineData
30fdf114 1## @file\r
52302d4d 2# This file is used to define common parsing related functions used in parsing INF/DEC/DSC process\r
30fdf114 3#\r
e4ac870f 4# Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>\r
40d841f6 5# This program and the accompanying materials\r
30fdf114
LG
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
17from String import *\r
18from CommonDataClass.DataClass import *\r
19from DataType import *\r
20\r
30fdf114
LG
21## ParseDefineMacro\r
22#\r
23# Search whole table to find all defined Macro and replaced them with the real values\r
24#\r
25def ParseDefineMacro2(Table, RecordSets, GlobalMacro):\r
26 Macros = {}\r
27 #\r
28 # Find all DEFINE macros in section [Header] and its section\r
29 #\r
30 SqlCommand = """select Value1, Value2, BelongsToItem, StartLine, Arch from %s\r
31 where Model = %s\r
32 and Enabled > -1""" % (Table.Table, MODEL_META_DATA_DEFINE)\r
33 RecordSet = Table.Exec(SqlCommand)\r
34 for Record in RecordSet:\r
35 Macros[Record[0]] = Record[1]\r
52302d4d 36\r
30fdf114
LG
37 #\r
38 # Overrided by Global Macros\r
39 #\r
40 for Key in GlobalMacro.keys():\r
41 Macros[Key] = GlobalMacro[Key]\r
52302d4d 42\r
30fdf114
LG
43 #\r
44 # Replace the Macros\r
45 #\r
46 for Key in RecordSets.keys():\r
47 if RecordSets[Key] != []:\r
48 for Item in RecordSets[Key]:\r
49 Item[0] = ReplaceMacro(Item[0], Macros)\r
52302d4d 50\r
30fdf114
LG
51## ParseDefineMacro\r
52#\r
53# Search whole table to find all defined Macro and replaced them with the real values\r
54#\r
55def ParseDefineMacro(Table, GlobalMacro):\r
56 Macros = {}\r
57 #\r
58 # Find all DEFINE macros\r
59 #\r
60 SqlCommand = """select Value1, Value2, BelongsToItem, StartLine, Arch from %s\r
61 where Model = %s\r
62 and Enabled > -1""" % (Table.Table, MODEL_META_DATA_DEFINE)\r
63 RecordSet = Table.Exec(SqlCommand)\r
64 for Record in RecordSet:\r
65#***************************************************************************************************************************************************\r
66# The follow SqlCommand (expr replace) is not supported in Sqlite 3.3.4 which is used in Python 2.5 *\r
67# Reserved Only *\r
68# SqlCommand = """update %s set Value1 = replace(Value1, '%s', '%s') *\r
52302d4d 69# where ID in (select ID from %s *\r
30fdf114
LG
70# where Model = %s *\r
71# and Value1 like '%%%s%%' *\r
72# and StartLine > %s *\r
73# and Enabled > -1 *\r
52302d4d 74# and Arch = '%s')""" % \ *\r
30fdf114
LG
75# (self.TblDsc.Table, Record[0], Record[1], self.TblDsc.Table, Record[2], Record[1], Record[3], Record[4]) *\r
76#***************************************************************************************************************************************************\r
77 Macros[Record[0]] = Record[1]\r
52302d4d 78\r
30fdf114
LG
79 #\r
80 # Overrided by Global Macros\r
81 #\r
82 for Key in GlobalMacro.keys():\r
83 Macros[Key] = GlobalMacro[Key]\r
52302d4d 84\r
30fdf114
LG
85 #\r
86 # Found all defined macro and replaced\r
87 #\r
88 SqlCommand = """select ID, Value1 from %s\r
89 where Model != %s\r
90 and Value1 like '%%$(%%' and Value1 like '%%)%%'\r
91 and Enabled > -1""" % (Table.Table, MODEL_META_DATA_DEFINE)\r
92 FoundRecords = Table.Exec(SqlCommand)\r
93 for FoundRecord in FoundRecords:\r
94 NewValue = ReplaceMacro(FoundRecord[1], Macros)\r
95 SqlCommand = """update %s set Value1 = '%s'\r
96 where ID = %s""" % (Table.Table, ConvertToSqlString2(NewValue), FoundRecord[0])\r
97 Table.Exec(SqlCommand)\r
98\r
99##QueryDefinesItem\r
100#\r
101# Search item of section [Defines] by name, return its values\r
102#\r
103# @param Table: The Table to be executed\r
104# @param Name: The Name of item of section [Defines]\r
105# @param Arch: The Arch of item of section [Defines]\r
106#\r
107# @retval RecordSet: A list of all matched records\r
108#\r
109def QueryDefinesItem(Table, Name, Arch, BelongsToFile):\r
110 SqlCommand = """select Value2 from %s\r
111 where Model = %s\r
112 and Value1 = '%s'\r
113 and Arch = '%s'\r
114 and BelongsToFile = %s\r
115 and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(Name), ConvertToSqlString2(Arch), BelongsToFile)\r
116 RecordSet = Table.Exec(SqlCommand)\r
117 if len(RecordSet) < 1:\r
118 SqlCommand = """select Value2 from %s\r
119 where Model = %s\r
120 and Value1 = '%s'\r
121 and Arch = '%s'\r
122 and BelongsToFile = %s\r
123 and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(Name), ConvertToSqlString2(TAB_ARCH_COMMON.upper()), BelongsToFile)\r
124 RecordSet = Table.Exec(SqlCommand)\r
125 if len(RecordSet) == 1:\r
126 if Name == TAB_INF_DEFINES_LIBRARY_CLASS:\r
127 return [RecordSet[0][0]]\r
128 else:\r
129 return GetSplitValueList(RecordSet[0][0])\r
130 elif len(RecordSet) < 1:\r
131 return ['']\r
132 elif len(RecordSet) > 1:\r
133 RetVal = []\r
134 for Record in RecordSet:\r
135 if Name == TAB_INF_DEFINES_LIBRARY_CLASS:\r
136 RetVal.append(Record[0])\r
137 else:\r
138 Items = GetSplitValueList(Record[0])\r
139 for Item in Items:\r
140 RetVal.append(Item)\r
141 return RetVal\r
142\r
143##QueryDefinesItem\r
144#\r
145# Search item of section [Defines] by name, return its values\r
146#\r
147# @param Table: The Table to be executed\r
148# @param Name: The Name of item of section [Defines]\r
149# @param Arch: The Arch of item of section [Defines]\r
150#\r
151# @retval RecordSet: A list of all matched records\r
152#\r
153def QueryDefinesItem2(Table, Arch, BelongsToFile):\r
154 SqlCommand = """select Value1, Value2, StartLine from %s\r
155 where Model = %s\r
156 and Arch = '%s'\r
157 and BelongsToFile = %s\r
158 and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(Arch), BelongsToFile)\r
159 RecordSet = Table.Exec(SqlCommand)\r
160 if len(RecordSet) < 1:\r
161 SqlCommand = """select Value1, Value2, StartLine from %s\r
162 where Model = %s\r
163 and Arch = '%s'\r
164 and BelongsToFile = %s\r
165 and Enabled > -1""" % (Table.Table, MODEL_META_DATA_HEADER, ConvertToSqlString2(TAB_ARCH_COMMON), BelongsToFile)\r
166 RecordSet = Table.Exec(SqlCommand)\r
52302d4d 167\r
30fdf114
LG
168 return RecordSet\r
169\r
170##QueryDscItem\r
171#\r
172# Search all dsc item for a specific section\r
173#\r
174# @param Table: The Table to be executed\r
175# @param Model: The type of section\r
176#\r
177# @retval RecordSet: A list of all matched records\r
178#\r
179def QueryDscItem(Table, Model, BelongsToItem, BelongsToFile):\r
180 SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s\r
181 where Model = %s\r
182 and BelongsToItem = %s\r
183 and BelongsToFile = %s\r
184 and Enabled > -1""" % (Table.Table, Model, BelongsToItem, BelongsToFile)\r
185 return Table.Exec(SqlCommand)\r
186\r
187##QueryDecItem\r
188#\r
189# Search all dec item for a specific section\r
190#\r
191# @param Table: The Table to be executed\r
192# @param Model: The type of section\r
193#\r
194# @retval RecordSet: A list of all matched records\r
195#\r
196def QueryDecItem(Table, Model, BelongsToItem):\r
197 SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s\r
198 where Model = %s\r
199 and BelongsToItem = %s\r
200 and Enabled > -1""" % (Table.Table, Model, BelongsToItem)\r
201 return Table.Exec(SqlCommand)\r
202\r
203##QueryInfItem\r
204#\r
205# Search all dec item for a specific section\r
206#\r
207# @param Table: The Table to be executed\r
208# @param Model: The type of section\r
209#\r
210# @retval RecordSet: A list of all matched records\r
211#\r
212def QueryInfItem(Table, Model, BelongsToItem):\r
213 SqlCommand = """select Value1, Arch, StartLine, ID, Value2 from %s\r
214 where Model = %s\r
215 and BelongsToItem = %s\r
216 and Enabled > -1""" % (Table.Table, Model, BelongsToItem)\r
217 return Table.Exec(SqlCommand)\r
218\r
219## GetBuildOption\r
220#\r
221# Parse a string with format "[<Family>:]<ToolFlag>=Flag"\r
222# Return (Family, ToolFlag, Flag)\r
223#\r
224# @param String: String with BuildOption statement\r
225# @param File: The file which defines build option, used in error report\r
226#\r
227# @retval truple() A truple structure as (Family, ToolChain, Flag)\r
228#\r
229def GetBuildOption(String, File, LineNo = -1):\r
636f2be6 230 (Family, ToolChain, Flag) = ('', '', '')\r
30fdf114
LG
231 if String.find(TAB_EQUAL_SPLIT) < 0:\r
232 RaiseParserError(String, 'BuildOptions', File, '[<Family>:]<ToolFlag>=Flag', LineNo)\r
30fdf114 233 else:\r
636f2be6
LG
234 List = GetSplitValueList(String, TAB_EQUAL_SPLIT, MaxSplit = 1)\r
235 if List[0].find(':') > -1:\r
236 Family = List[0][ : List[0].find(':')].strip()\r
237 ToolChain = List[0][List[0].find(':') + 1 : ].strip()\r
238 else:\r
239 ToolChain = List[0].strip()\r
240 Flag = List[1].strip()\r
30fdf114
LG
241 return (Family, ToolChain, Flag)\r
242\r
243## Get Library Class\r
244#\r
245# Get Library of Dsc as <LibraryClassKeyWord>|<LibraryInstance>\r
52302d4d 246#\r
30fdf114
LG
247# @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>\r
248# @param ContainerFile: The file which describes the library class, used for error report\r
249#\r
250# @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item\r
251#\r
252def GetLibraryClass(Item, ContainerFile, WorkspaceDir, LineNo = -1):\r
253 List = GetSplitValueList(Item[0])\r
254 SupMod = SUP_MODULE_LIST_STRING\r
255 if len(List) != 2:\r
256 RaiseParserError(Item[0], 'LibraryClasses', ContainerFile, '<LibraryClassKeyWord>|<LibraryInstance>')\r
257 else:\r
258 CheckFileType(List[1], '.Inf', ContainerFile, 'library class instance', Item[0], LineNo)\r
259 CheckFileExist(WorkspaceDir, List[1], ContainerFile, 'LibraryClasses', Item[0], LineNo)\r
260 if Item[1] != '':\r
261 SupMod = Item[1]\r
262\r
263 return (List[0], List[1], SupMod)\r
264\r
265## Get Library Class\r
266#\r
267# Get Library of Dsc as <LibraryClassKeyWord>[|<LibraryInstance>][|<TokenSpaceGuidCName>.<PcdCName>]\r
52302d4d 268#\r
30fdf114
LG
269# @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>\r
270# @param ContainerFile: The file which describes the library class, used for error report\r
271#\r
272# @retval (LibraryClassKeyWord, LibraryInstance, [SUP_MODULE_LIST]) Formatted Library Item\r
273#\r
274def GetLibraryClassOfInf(Item, ContainerFile, WorkspaceDir, LineNo = -1):\r
275 ItemList = GetSplitValueList((Item[0] + DataType.TAB_VALUE_SPLIT * 2))\r
276 SupMod = SUP_MODULE_LIST_STRING\r
277\r
278 if len(ItemList) > 5:\r
279 RaiseParserError(Item[0], 'LibraryClasses', ContainerFile, '<LibraryClassKeyWord>[|<LibraryInstance>][|<TokenSpaceGuidCName>.<PcdCName>]')\r
280 else:\r
281 CheckFileType(ItemList[1], '.Inf', ContainerFile, 'LibraryClasses', Item[0], LineNo)\r
282 CheckFileExist(WorkspaceDir, ItemList[1], ContainerFile, 'LibraryClasses', Item[0], LineNo)\r
283 if ItemList[2] != '':\r
284 CheckPcdTokenInfo(ItemList[2], 'LibraryClasses', ContainerFile, LineNo)\r
285 if Item[1] != '':\r
286 SupMod = Item[1]\r
287\r
52302d4d 288 return (ItemList[0], ItemList[1], ItemList[2], SupMod)\r
30fdf114
LG
289\r
290## CheckPcdTokenInfo\r
291#\r
292# Check if PcdTokenInfo is following <TokenSpaceGuidCName>.<PcdCName>\r
293#\r
294# @param TokenInfoString: String to be checked\r
295# @param Section: Used for error report\r
296# @param File: Used for error report\r
297#\r
298# @retval True PcdTokenInfo is in correct format\r
299#\r
300def CheckPcdTokenInfo(TokenInfoString, Section, File, LineNo = -1):\r
301 Format = '<TokenSpaceGuidCName>.<PcdCName>'\r
302 if TokenInfoString != '' and TokenInfoString != None:\r
303 TokenInfoList = GetSplitValueList(TokenInfoString, TAB_SPLIT)\r
304 if len(TokenInfoList) == 2:\r
305 return True\r
306\r
307 RaiseParserError(TokenInfoString, Section, File, Format, LineNo)\r
308\r
309## Get Pcd\r
310#\r
311# Get Pcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]\r
52302d4d 312#\r
30fdf114
LG
313# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]\r
314# @param ContainerFile: The file which describes the pcd, used for error report\r
315#\r
316# @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type)\r
317#\r
318def GetPcd(Item, Type, ContainerFile, LineNo = -1):\r
319 TokenGuid, TokenName, Value, MaximumDatumSize, Token = '', '', '', '', ''\r
320 List = GetSplitValueList(Item + TAB_VALUE_SPLIT * 2)\r
52302d4d 321\r
30fdf114
LG
322 if len(List) < 4 or len(List) > 6:\r
323 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<Type>|<MaximumDatumSize>]', LineNo)\r
324 else:\r
325 Value = List[1]\r
326 MaximumDatumSize = List[2]\r
327 Token = List[3]\r
52302d4d 328\r
30fdf114
LG
329 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):\r
330 (TokenGuid, TokenName) = GetSplitValueList(List[0], TAB_SPLIT)\r
52302d4d 331\r
30fdf114
LG
332 return (TokenName, TokenGuid, Value, MaximumDatumSize, Token, Type)\r
333\r
334## Get FeatureFlagPcd\r
335#\r
336# Get FeatureFlagPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE\r
52302d4d 337#\r
30fdf114
LG
338# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE\r
339# @param ContainerFile: The file which describes the pcd, used for error report\r
340#\r
341# @retval (TokenInfo[1], TokenInfo[0], List[1], Type)\r
342#\r
343def GetFeatureFlagPcd(Item, Type, ContainerFile, LineNo = -1):\r
344 TokenGuid, TokenName, Value = '', '', ''\r
345 List = GetSplitValueList(Item)\r
346 if len(List) != 2:\r
347 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE', LineNo)\r
348 else:\r
349 Value = List[1]\r
350 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):\r
351 (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)\r
52302d4d 352\r
30fdf114
LG
353 return (TokenName, TokenGuid, Value, Type)\r
354\r
355## Get DynamicDefaultPcd\r
356#\r
357# Get DynamicDefaultPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<DatumTyp>[|<MaxDatumSize>]]\r
52302d4d 358#\r
30fdf114
LG
359# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE\r
360# @param ContainerFile: The file which describes the pcd, used for error report\r
361#\r
362# @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], Type)\r
363#\r
364def GetDynamicDefaultPcd(Item, Type, ContainerFile, LineNo = -1):\r
365 TokenGuid, TokenName, Value, DatumTyp, MaxDatumSize = '', '', '', '', ''\r
366 List = GetSplitValueList(Item + TAB_VALUE_SPLIT * 2)\r
367 if len(List) < 4 or len(List) > 8:\r
368 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>[|<DatumTyp>[|<MaxDatumSize>]]', LineNo)\r
369 else:\r
370 Value = List[1]\r
371 DatumTyp = List[2]\r
372 MaxDatumSize = List[3]\r
373 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):\r
374 (TokenGuid, TokenName) = GetSplitValueList(List[0], TAB_SPLIT)\r
52302d4d 375\r
30fdf114
LG
376 return (TokenName, TokenGuid, Value, DatumTyp, MaxDatumSize, Type)\r
377\r
378## Get DynamicHiiPcd\r
379#\r
380# Get DynamicHiiPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<String>|<VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]\r
52302d4d 381#\r
30fdf114
LG
382# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE\r
383# @param ContainerFile: The file which describes the pcd, used for error report\r
384#\r
385# @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], List[3], List[4], List[5], Type)\r
386#\r
387def GetDynamicHiiPcd(Item, Type, ContainerFile, LineNo = -1):\r
388 TokenGuid, TokenName, L1, L2, L3, L4, L5 = '', '', '', '', '', '', ''\r
389 List = GetSplitValueList(Item + TAB_VALUE_SPLIT * 2)\r
390 if len(List) < 6 or len(List) > 8:\r
391 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|<String>|<VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]', LineNo)\r
392 else:\r
393 L1, L2, L3, L4, L5 = List[1], List[2], List[3], List[4], List[5]\r
394 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):\r
395 (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)\r
52302d4d 396\r
30fdf114
LG
397 return (TokenName, TokenGuid, L1, L2, L3, L4, L5, Type)\r
398\r
399## Get DynamicVpdPcd\r
400#\r
401# Get DynamicVpdPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>[|<MaximumDatumSize>]\r
52302d4d 402#\r
30fdf114
LG
403# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE\r
404# @param ContainerFile: The file which describes the pcd, used for error report\r
405#\r
406# @retval (TokenInfo[1], TokenInfo[0], List[1], List[2], Type)\r
407#\r
408def GetDynamicVpdPcd(Item, Type, ContainerFile, LineNo = -1):\r
409 TokenGuid, TokenName, L1, L2 = '', '', '', ''\r
410 List = GetSplitValueList(Item + TAB_VALUE_SPLIT)\r
411 if len(List) < 3 or len(List) > 4:\r
412 RaiseParserError(Item, 'Pcds' + Type, ContainerFile, '<PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>[|<MaximumDatumSize>]', LineNo)\r
413 else:\r
414 L1, L2 = List[1], List[2]\r
415 if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):\r
416 (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)\r
52302d4d 417\r
30fdf114
LG
418 return (TokenName, TokenGuid, L1, L2, Type)\r
419\r
420## GetComponent\r
421#\r
422# Parse block of the components defined in dsc file\r
423# Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...]\r
424#\r
425# @param Lines: The content to be parsed\r
426# @param KeyValues: To store data after parsing\r
427#\r
428# @retval True Get component successfully\r
429#\r
430def GetComponent(Lines, KeyValues):\r
431 (findBlock, findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, False, False)\r
432 ListItem = None\r
433 LibraryClassItem = []\r
434 BuildOption = []\r
435 Pcd = []\r
436\r
437 for Line in Lines:\r
438 Line = Line[0]\r
52302d4d 439\r
30fdf114
LG
440 #\r
441 # Ignore !include statement\r
442 #\r
443 if Line.upper().find(TAB_INCLUDE.upper() + ' ') > -1 or Line.upper().find(TAB_DEFINE + ' ') > -1:\r
444 continue\r
52302d4d 445\r
30fdf114
LG
446 if findBlock == False:\r
447 ListItem = Line\r
448 #\r
449 # find '{' at line tail\r
450 #\r
451 if Line.endswith('{'):\r
452 findBlock = True\r
453 ListItem = CleanString(Line.rsplit('{', 1)[0], DataType.TAB_COMMENT_SPLIT)\r
454\r
455 #\r
456 # Parse a block content\r
457 #\r
458 if findBlock:\r
459 if Line.find('<LibraryClasses>') != -1:\r
460 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (True, False, False, False, False, False, False)\r
461 continue\r
462 if Line.find('<BuildOptions>') != -1:\r
463 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, True, False, False, False, False, False)\r
464 continue\r
465 if Line.find('<PcdsFeatureFlag>') != -1:\r
466 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, True, False, False, False, False)\r
467 continue\r
468 if Line.find('<PcdsPatchableInModule>') != -1:\r
469 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, True, False, False, False)\r
470 continue\r
471 if Line.find('<PcdsFixedAtBuild>') != -1:\r
472 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, True, False, False)\r
473 continue\r
474 if Line.find('<PcdsDynamic>') != -1:\r
475 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, True, False)\r
476 continue\r
477 if Line.find('<PcdsDynamicEx>') != -1:\r
478 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, True)\r
479 continue\r
480 if Line.endswith('}'):\r
481 #\r
482 # find '}' at line tail\r
483 #\r
484 KeyValues.append([ListItem, LibraryClassItem, BuildOption, Pcd])\r
485 (findBlock, findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, False, False)\r
486 LibraryClassItem, BuildOption, Pcd = [], [], []\r
487 continue\r
488\r
489 if findBlock:\r
490 if findLibraryClass:\r
491 LibraryClassItem.append(Line)\r
492 elif findBuildOption:\r
493 BuildOption.append(Line)\r
494 elif findPcdsFeatureFlag:\r
495 Pcd.append((DataType.TAB_PCDS_FEATURE_FLAG_NULL, Line))\r
496 elif findPcdsPatchableInModule:\r
497 Pcd.append((DataType.TAB_PCDS_PATCHABLE_IN_MODULE_NULL, Line))\r
498 elif findPcdsFixedAtBuild:\r
499 Pcd.append((DataType.TAB_PCDS_FIXED_AT_BUILD_NULL, Line))\r
500 elif findPcdsDynamic:\r
501 Pcd.append((DataType.TAB_PCDS_DYNAMIC_DEFAULT_NULL, Line))\r
502 elif findPcdsDynamicEx:\r
503 Pcd.append((DataType.TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL, Line))\r
504 else:\r
505 KeyValues.append([ListItem, [], [], []])\r
506\r
507 return True\r
508\r
509## GetExec\r
510#\r
511# Parse a string with format "InfFilename [EXEC = ExecFilename]"\r
512# Return (InfFilename, ExecFilename)\r
513#\r
514# @param String: String with EXEC statement\r
515#\r
516# @retval truple() A pair as (InfFilename, ExecFilename)\r
517#\r
518def GetExec(String):\r
519 InfFilename = ''\r
520 ExecFilename = ''\r
521 if String.find('EXEC') > -1:\r
522 InfFilename = String[ : String.find('EXEC')].strip()\r
523 ExecFilename = String[String.find('EXEC') + len('EXEC') : ].strip()\r
524 else:\r
525 InfFilename = String.strip()\r
526\r
527 return (InfFilename, ExecFilename)\r
528\r
529## GetComponents\r
530#\r
531# Parse block of the components defined in dsc file\r
532# Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...]\r
533#\r
534# @param Lines: The content to be parsed\r
52302d4d 535# @param Key: Reserved\r
30fdf114
LG
536# @param KeyValues: To store data after parsing\r
537# @param CommentCharacter: Comment char, used to ignore comment content\r
538#\r
539# @retval True Get component successfully\r
540#\r
541def GetComponents(Lines, Key, KeyValues, CommentCharacter):\r
542 if Lines.find(DataType.TAB_SECTION_END) > -1:\r
543 Lines = Lines.split(DataType.TAB_SECTION_END, 1)[1]\r
544 (findBlock, findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, False, False)\r
545 ListItem = None\r
546 LibraryClassItem = []\r
547 BuildOption = []\r
548 Pcd = []\r
549\r
550 LineList = Lines.split('\n')\r
551 for Line in LineList:\r
552 Line = CleanString(Line, CommentCharacter)\r
553 if Line == None or Line == '':\r
554 continue\r
555\r
556 if findBlock == False:\r
557 ListItem = Line\r
558 #\r
559 # find '{' at line tail\r
560 #\r
561 if Line.endswith('{'):\r
562 findBlock = True\r
563 ListItem = CleanString(Line.rsplit('{', 1)[0], CommentCharacter)\r
564\r
565 #\r
566 # Parse a block content\r
567 #\r
568 if findBlock:\r
569 if Line.find('<LibraryClasses>') != -1:\r
570 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (True, False, False, False, False, False, False)\r
571 continue\r
572 if Line.find('<BuildOptions>') != -1:\r
573 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, True, False, False, False, False, False)\r
574 continue\r
575 if Line.find('<PcdsFeatureFlag>') != -1:\r
576 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, True, False, False, False, False)\r
577 continue\r
578 if Line.find('<PcdsPatchableInModule>') != -1:\r
579 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, True, False, False, False)\r
580 continue\r
581 if Line.find('<PcdsFixedAtBuild>') != -1:\r
582 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, True, False, False)\r
583 continue\r
584 if Line.find('<PcdsDynamic>') != -1:\r
585 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, True, False)\r
586 continue\r
587 if Line.find('<PcdsDynamicEx>') != -1:\r
588 (findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, True)\r
589 continue\r
590 if Line.endswith('}'):\r
591 #\r
592 # find '}' at line tail\r
593 #\r
594 KeyValues.append([ListItem, LibraryClassItem, BuildOption, Pcd])\r
595 (findBlock, findLibraryClass, findBuildOption, findPcdsFeatureFlag, findPcdsPatchableInModule, findPcdsFixedAtBuild, findPcdsDynamic, findPcdsDynamicEx) = (False, False, False, False, False, False, False, False)\r
596 LibraryClassItem, BuildOption, Pcd = [], [], []\r
597 continue\r
598\r
599 if findBlock:\r
600 if findLibraryClass:\r
601 LibraryClassItem.append(Line)\r
602 elif findBuildOption:\r
603 BuildOption.append(Line)\r
604 elif findPcdsFeatureFlag:\r
605 Pcd.append((DataType.TAB_PCDS_FEATURE_FLAG, Line))\r
606 elif findPcdsPatchableInModule:\r
607 Pcd.append((DataType.TAB_PCDS_PATCHABLE_IN_MODULE, Line))\r
608 elif findPcdsFixedAtBuild:\r
609 Pcd.append((DataType.TAB_PCDS_FIXED_AT_BUILD, Line))\r
610 elif findPcdsDynamic:\r
611 Pcd.append((DataType.TAB_PCDS_DYNAMIC, Line))\r
612 elif findPcdsDynamicEx:\r
613 Pcd.append((DataType.TAB_PCDS_DYNAMIC_EX, Line))\r
614 else:\r
615 KeyValues.append([ListItem, [], [], []])\r
616\r
617 return True\r
618\r
619## Get Source\r
620#\r
621# Get Source of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]\r
52302d4d 622#\r
30fdf114
LG
623# @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]\r
624# @param ContainerFile: The file which describes the library class, used for error report\r
625#\r
626# @retval (List[0], List[1], List[2], List[3], List[4])\r
627#\r
628def GetSource(Item, ContainerFile, FileRelativePath, LineNo = -1):\r
629 ItemNew = Item + DataType.TAB_VALUE_SPLIT * 4\r
630 List = GetSplitValueList(ItemNew)\r
631 if len(List) < 5 or len(List) > 9:\r
632 RaiseParserError(Item, 'Sources', ContainerFile, '<Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]', LineNo)\r
633 List[0] = NormPath(List[0])\r
634 CheckFileExist(FileRelativePath, List[0], ContainerFile, 'Sources', Item, LineNo)\r
635 if List[4] != '':\r
636 CheckPcdTokenInfo(List[4], 'Sources', ContainerFile, LineNo)\r
637\r
638 return (List[0], List[1], List[2], List[3], List[4])\r
639\r
640## Get Binary\r
641#\r
642# Get Binary of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]\r
52302d4d 643#\r
30fdf114
LG
644# @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]\r
645# @param ContainerFile: The file which describes the library class, used for error report\r
646#\r
647# @retval (List[0], List[1], List[2], List[3])\r
52302d4d 648# @retval List\r
30fdf114
LG
649#\r
650def GetBinary(Item, ContainerFile, FileRelativePath, LineNo = -1):\r
651 ItemNew = Item + DataType.TAB_VALUE_SPLIT\r
652 List = GetSplitValueList(ItemNew)\r
653 if len(List) != 4 and len(List) != 5:\r
654 RaiseParserError(Item, 'Binaries', ContainerFile, "<FileType>|<Filename>|<Target>[|<TokenSpaceGuidCName>.<PcdCName>]", LineNo)\r
655 else:\r
656 if List[3] != '':\r
657 CheckPcdTokenInfo(List[3], 'Binaries', ContainerFile, LineNo)\r
52302d4d
LG
658\r
659 if len(List) == 4:\r
660 return (List[0], List[1], List[2], List[3])\r
661 elif len(List) == 3:\r
662 return (List[0], List[1], List[2], '')\r
663 elif len(List) == 2:\r
664 return (List[0], List[1], '', '')\r
665 elif len(List) == 1:\r
666 return (List[0], '', '', '')\r
30fdf114
LG
667\r
668## Get Guids/Protocols/Ppis\r
669#\r
670# Get Guids/Protocols/Ppis of Inf as <GuidCName>[|<PcdFeatureFlag>]\r
671#\r
672# @param Item: String as <GuidCName>[|<PcdFeatureFlag>]\r
52302d4d 673# @param Type: Type of parsing string\r
30fdf114
LG
674# @param ContainerFile: The file which describes the library class, used for error report\r
675#\r
676# @retval (List[0], List[1])\r
677#\r
678def GetGuidsProtocolsPpisOfInf(Item, Type, ContainerFile, LineNo = -1):\r
679 ItemNew = Item + TAB_VALUE_SPLIT\r
680 List = GetSplitValueList(ItemNew)\r
681 if List[1] != '':\r
682 CheckPcdTokenInfo(List[1], Type, ContainerFile, LineNo)\r
52302d4d 683\r
30fdf114
LG
684 return (List[0], List[1])\r
685\r
686## Get Guids/Protocols/Ppis\r
687#\r
688# Get Guids/Protocols/Ppis of Dec as <GuidCName>=<GuidValue>\r
689#\r
690# @param Item: String as <GuidCName>=<GuidValue>\r
52302d4d 691# @param Type: Type of parsing string\r
30fdf114
LG
692# @param ContainerFile: The file which describes the library class, used for error report\r
693#\r
694# @retval (List[0], List[1])\r
695#\r
696def GetGuidsProtocolsPpisOfDec(Item, Type, ContainerFile, LineNo = -1):\r
697 List = GetSplitValueList(Item, DataType.TAB_EQUAL_SPLIT)\r
698 if len(List) != 2:\r
699 RaiseParserError(Item, Type, ContainerFile, '<CName>=<GuidValue>', LineNo)\r
52302d4d 700\r
30fdf114
LG
701 return (List[0], List[1])\r
702\r
703## GetPackage\r
704#\r
705# Get Package of Inf as <PackagePath>[|<PcdFeatureFlag>]\r
706#\r
707# @param Item: String as <PackagePath>[|<PcdFeatureFlag>]\r
52302d4d 708# @param Type: Type of parsing string\r
30fdf114
LG
709# @param ContainerFile: The file which describes the library class, used for error report\r
710#\r
711# @retval (List[0], List[1])\r
712#\r
713def GetPackage(Item, ContainerFile, FileRelativePath, LineNo = -1):\r
714 ItemNew = Item + TAB_VALUE_SPLIT\r
715 List = GetSplitValueList(ItemNew)\r
716 CheckFileType(List[0], '.Dec', ContainerFile, 'package', List[0], LineNo)\r
717 CheckFileExist(FileRelativePath, List[0], ContainerFile, 'Packages', List[0], LineNo)\r
52302d4d 718\r
30fdf114
LG
719 if List[1] != '':\r
720 CheckPcdTokenInfo(List[1], 'Packages', ContainerFile, LineNo)\r
52302d4d 721\r
30fdf114
LG
722 return (List[0], List[1])\r
723\r
724## Get Pcd Values of Inf\r
725#\r
726# Get Pcd of Inf as <TokenSpaceGuidCName>.<PcdCName>[|<Value>]\r
727#\r
728# @param Item: The string describes pcd\r
729# @param Type: The type of Pcd\r
730# @param File: The file which describes the pcd, used for error report\r
731#\r
732# @retval (TokenSpcCName, TokenCName, Value, ItemType) Formatted Pcd Item\r
733#\r
734def GetPcdOfInf(Item, Type, File, LineNo):\r
735 Format = '<TokenSpaceGuidCName>.<PcdCName>[|<Value>]'\r
736 TokenGuid, TokenName, Value, InfType = '', '', '', ''\r
52302d4d 737\r
30fdf114
LG
738 if Type == TAB_PCDS_FIXED_AT_BUILD:\r
739 InfType = TAB_INF_FIXED_PCD\r
740 elif Type == TAB_PCDS_PATCHABLE_IN_MODULE:\r
741 InfType = TAB_INF_PATCH_PCD\r
742 elif Type == TAB_PCDS_FEATURE_FLAG:\r
52302d4d 743 InfType = TAB_INF_FEATURE_PCD\r
30fdf114 744 elif Type == TAB_PCDS_DYNAMIC_EX:\r
52302d4d 745 InfType = TAB_INF_PCD_EX\r
30fdf114
LG
746 elif Type == TAB_PCDS_DYNAMIC:\r
747 InfType = TAB_INF_PCD\r
748 List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT)\r
749 if len(List) < 2 or len(List) > 3:\r
750 RaiseParserError(Item, InfType, File, Format, LineNo)\r
751 else:\r
752 Value = List[1]\r
753 TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT)\r
754 if len(TokenInfo) != 2:\r
755 RaiseParserError(Item, InfType, File, Format, LineNo)\r
756 else:\r
757 TokenGuid = TokenInfo[0]\r
758 TokenName = TokenInfo[1]\r
759\r
760 return (TokenGuid, TokenName, Value, Type)\r
761\r
52302d4d 762\r
30fdf114
LG
763## Get Pcd Values of Dec\r
764#\r
765# Get Pcd of Dec as <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>\r
766# @retval (TokenSpcCName, TokenCName, Value, DatumType, Token, ItemType) Formatted Pcd Item\r
767#\r
768def GetPcdOfDec(Item, Type, File, LineNo = -1):\r
769 Format = '<TokenSpaceGuidCName>.<PcdCName>|<Value>|<DatumType>|<Token>'\r
770 TokenGuid, TokenName, Value, DatumType, Token = '', '', '', '', ''\r
771 List = GetSplitValueList(Item)\r
772 if len(List) != 4:\r
773 RaiseParserError(Item, 'Pcds' + Type, File, Format, LineNo)\r
774 else:\r
775 Value = List[1]\r
776 DatumType = List[2]\r
777 Token = List[3]\r
778 TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT)\r
779 if len(TokenInfo) != 2:\r
780 RaiseParserError(Item, 'Pcds' + Type, File, Format, LineNo)\r
781 else:\r
782 TokenGuid = TokenInfo[0]\r
783 TokenName = TokenInfo[1]\r
52302d4d 784\r
30fdf114
LG
785 return (TokenGuid, TokenName, Value, DatumType, Token, Type)\r
786\r
787## Parse DEFINE statement\r
788#\r
789# Get DEFINE macros\r
790#\r
791# 1. Insert a record into TblDec\r
792# Value1: Macro Name\r
793# Value2: Macro Value\r
794#\r
795def ParseDefine(LineValue, StartLine, Table, FileID, Filename, SectionName, SectionModel, Arch):\r
796 EdkLogger.debug(EdkLogger.DEBUG_2, "DEFINE statement '%s' found in section %s" % (LineValue, SectionName))\r
797 Define = GetSplitValueList(CleanString(LineValue[LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') + len(DataType.TAB_DEFINE + ' ') : ]), TAB_EQUAL_SPLIT, 1)\r
798 Table.Insert(MODEL_META_DATA_DEFINE, Define[0], Define[1], '', '', '', Arch, SectionModel, FileID, StartLine, -1, StartLine, -1, 0)\r
799\r
800## InsertSectionItems\r
52302d4d 801#\r
30fdf114
LG
802# Insert item data of a section to a dict\r
803#\r
804def InsertSectionItems(Model, CurrentSection, SectionItemList, ArchList, ThirdList, RecordSet):\r
805 # Insert each item data of a section\r
806 for Index in range(0, len(ArchList)):\r
807 Arch = ArchList[Index]\r
808 Third = ThirdList[Index]\r
809 if Arch == '':\r
810 Arch = TAB_ARCH_COMMON\r
811\r
812 Records = RecordSet[Model]\r
813 for SectionItem in SectionItemList:\r
814 BelongsToItem, EndLine, EndColumn = -1, -1, -1\r
815 LineValue, StartLine, EndLine, Comment = SectionItem[0], SectionItem[1], SectionItem[1], SectionItem[2]\r
52302d4d 816\r
30fdf114
LG
817 EdkLogger.debug(4, "Parsing %s ..." %LineValue)\r
818 # And then parse DEFINE statement\r
819 if LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') > -1:\r
820 continue\r
52302d4d 821\r
30fdf114
LG
822 # At last parse other sections\r
823 ID = -1\r
824 Records.append([LineValue, Arch, StartLine, ID, Third, Comment])\r
52302d4d 825\r
30fdf114
LG
826 if RecordSet != {}:\r
827 RecordSet[Model] = Records\r
828\r
829## Insert records to database\r
52302d4d 830#\r
30fdf114 831# Insert item data of a section to database\r
52302d4d 832# @param Table: The Table to be inserted\r
30fdf114
LG
833# @param FileID: The ID of belonging file\r
834# @param Filename: The name of belonging file\r
835# @param CurrentSection: The name of currect section\r
836# @param SectionItemList: A list of items of the section\r
837# @param ArchList: A list of arches\r
838# @param ThirdList: A list of third parameters, ModuleType for LibraryClass and SkuId for Dynamic Pcds\r
839# @param IfDefList: A list of all conditional statements\r
52302d4d 840# @param RecordSet: A dict of all parsed records\r
30fdf114
LG
841#\r
842def InsertSectionItemsIntoDatabase(Table, FileID, Filename, Model, CurrentSection, SectionItemList, ArchList, ThirdList, IfDefList, RecordSet):\r
843 #\r
844 # Insert each item data of a section\r
845 #\r
846 for Index in range(0, len(ArchList)):\r
847 Arch = ArchList[Index]\r
848 Third = ThirdList[Index]\r
849 if Arch == '':\r
850 Arch = TAB_ARCH_COMMON\r
851\r
852 Records = RecordSet[Model]\r
853 for SectionItem in SectionItemList:\r
854 BelongsToItem, EndLine, EndColumn = -1, -1, -1\r
855 LineValue, StartLine, EndLine = SectionItem[0], SectionItem[1], SectionItem[1]\r
52302d4d 856\r
30fdf114
LG
857 EdkLogger.debug(4, "Parsing %s ..." %LineValue)\r
858 #\r
859 # And then parse DEFINE statement\r
860 #\r
861 if LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') > -1:\r
862 ParseDefine(LineValue, StartLine, Table, FileID, Filename, CurrentSection, Model, Arch)\r
863 continue\r
52302d4d 864\r
30fdf114
LG
865 #\r
866 # At last parse other sections\r
867 #\r
868 ID = Table.Insert(Model, LineValue, Third, Third, '', '', Arch, -1, FileID, StartLine, -1, StartLine, -1, 0)\r
869 Records.append([LineValue, Arch, StartLine, ID, Third])\r
52302d4d 870\r
30fdf114
LG
871 if RecordSet != {}:\r
872 RecordSet[Model] = Records\r
873\r
874## GenMetaDatSectionItem\r
875def GenMetaDatSectionItem(Key, Value, List):\r
876 if Key not in List:\r
877 List[Key] = [Value]\r
878 else:\r
6780eef1 879 List[Key].append(Value)\r
e4ac870f
LG
880\r
881## IsValidWord\r
882#\r
883# Check whether the word is valid.\r
884# <Word> ::= (a-zA-Z0-9_)(a-zA-Z0-9_-){0,} Alphanumeric characters with\r
885# optional\r
886# dash "-" and/or underscore "_" characters. No whitespace\r
887# characters are permitted.\r
888#\r
889# @param Word: The word string need to be checked.\r
890#\r
891def IsValidWord(Word):\r
892 if not Word:\r
893 return False\r
894 #\r
895 # The first char should be alpha, _ or Digit.\r
896 #\r
897 if not Word[0].isalnum() and \\r
898 not Word[0] == '_' and \\r
899 not Word[0].isdigit():\r
900 return False\r
901\r
902 LastChar = ''\r
903 for Char in Word[1:]:\r
904 if (not Char.isalpha()) and \\r
905 (not Char.isdigit()) and \\r
906 Char != '-' and \\r
907 Char != '_' and \\r
908 Char != '.':\r
909 return False\r
910 if Char == '.' and LastChar == '.':\r
911 return False\r
912 LastChar = Char\r
913\r
914 return True\r