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