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