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