]>
Commit | Line | Data |
---|---|---|
4234283c LG |
1 | ## @file\r |
2 | # This file is used to define comment parsing interface\r | |
3 | #\r | |
64285f15 | 4 | # Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r |
4234283c | 5 | #\r |
f7496d71 LG |
6 | # This program and the accompanying materials are licensed and made available\r |
7 | # under the terms and conditions of the BSD License which accompanies this\r | |
8 | # distribution. The full text of the license may be found at\r | |
4234283c LG |
9 | # http://opensource.org/licenses/bsd-license.php\r |
10 | #\r | |
11 | # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
12 | # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
13 | #\r | |
14 | \r | |
15 | '''\r | |
16 | CommentParsing\r | |
17 | '''\r | |
18 | \r | |
19 | ##\r | |
20 | # Import Modules\r | |
21 | #\r | |
22 | import re\r | |
23 | \r | |
64285f15 YZ |
24 | from Library.StringUtils import GetSplitValueList\r |
25 | from Library.StringUtils import CleanString2\r | |
4234283c LG |
26 | from Library.DataType import HEADER_COMMENT_NOT_STARTED\r |
27 | from Library.DataType import TAB_COMMENT_SPLIT\r | |
28 | from Library.DataType import HEADER_COMMENT_LICENSE\r | |
29 | from Library.DataType import HEADER_COMMENT_ABSTRACT\r | |
30 | from Library.DataType import HEADER_COMMENT_COPYRIGHT\r | |
31 | from Library.DataType import HEADER_COMMENT_DESCRIPTION\r | |
32 | from Library.DataType import TAB_SPACE_SPLIT\r | |
33 | from Library.DataType import TAB_COMMA_SPLIT\r | |
34 | from Library.DataType import SUP_MODULE_LIST\r | |
421ccda3 HC |
35 | from Library.DataType import TAB_VALUE_SPLIT\r |
36 | from Library.DataType import TAB_PCD_VALIDRANGE\r | |
37 | from Library.DataType import TAB_PCD_VALIDLIST\r | |
38 | from Library.DataType import TAB_PCD_EXPRESSION\r | |
39 | from Library.DataType import TAB_PCD_PROMPT\r | |
40 | from Library.DataType import TAB_CAPHEX_START\r | |
41 | from Library.DataType import TAB_HEX_START\r | |
42 | from Library.DataType import PCD_ERR_CODE_MAX_SIZE\r | |
43 | from Library.ExpressionValidate import IsValidRangeExpr\r | |
44 | from Library.ExpressionValidate import IsValidListExpr\r | |
45 | from Library.ExpressionValidate import IsValidLogicalExpr\r | |
4234283c LG |
46 | from Object.POM.CommonObject import TextObject\r |
47 | from Object.POM.CommonObject import PcdErrorObject\r | |
48 | import Logger.Log as Logger\r | |
49 | from Logger.ToolError import FORMAT_INVALID\r | |
50 | from Logger.ToolError import FORMAT_NOT_SUPPORTED\r | |
51 | from Logger import StringTable as ST\r | |
52 | \r | |
53 | ## ParseHeaderCommentSection\r | |
54 | #\r | |
55 | # Parse Header comment section lines, extract Abstract, Description, Copyright\r | |
56 | # , License lines\r | |
57 | #\r | |
58 | # @param CommentList: List of (Comment, LineNumber)\r | |
59 | # @param FileName: FileName of the comment\r | |
60 | #\r | |
421ccda3 | 61 | def ParseHeaderCommentSection(CommentList, FileName = None, IsBinaryHeader = False):\r |
4234283c LG |
62 | Abstract = ''\r |
63 | Description = ''\r | |
64 | Copyright = ''\r | |
65 | License = ''\r | |
66 | EndOfLine = "\n"\r | |
421ccda3 HC |
67 | if IsBinaryHeader:\r |
68 | STR_HEADER_COMMENT_START = "@BinaryHeader"\r | |
69 | else:\r | |
70 | STR_HEADER_COMMENT_START = "@file"\r | |
4234283c | 71 | HeaderCommentStage = HEADER_COMMENT_NOT_STARTED\r |
f7496d71 | 72 | \r |
4234283c LG |
73 | #\r |
74 | # first find the last copyright line\r | |
75 | #\r | |
76 | Last = 0\r | |
174a9d3c | 77 | for Index in range(len(CommentList)-1, 0, -1):\r |
4234283c LG |
78 | Line = CommentList[Index][0]\r |
79 | if _IsCopyrightLine(Line):\r | |
80 | Last = Index\r | |
81 | break\r | |
f7496d71 | 82 | \r |
4234283c LG |
83 | for Item in CommentList:\r |
84 | Line = Item[0]\r | |
85 | LineNo = Item[1]\r | |
f7496d71 | 86 | \r |
4234283c LG |
87 | if not Line.startswith(TAB_COMMENT_SPLIT) and Line:\r |
88 | Logger.Error("\nUPT", FORMAT_INVALID, ST.ERR_INVALID_COMMENT_FORMAT, FileName, Item[1])\r | |
89 | Comment = CleanString2(Line)[1]\r | |
90 | Comment = Comment.strip()\r | |
91 | #\r | |
f7496d71 | 92 | # if there are blank lines between License or Description, keep them as they would be\r |
4234283c LG |
93 | # indication of different block; or in the position that Abstract should be, also keep it\r |
94 | # as it indicates that no abstract\r | |
95 | #\r | |
96 | if not Comment and HeaderCommentStage not in [HEADER_COMMENT_LICENSE, \\r | |
97 | HEADER_COMMENT_DESCRIPTION, HEADER_COMMENT_ABSTRACT]:\r | |
98 | continue\r | |
f7496d71 | 99 | \r |
4234283c LG |
100 | if HeaderCommentStage == HEADER_COMMENT_NOT_STARTED:\r |
101 | if Comment.startswith(STR_HEADER_COMMENT_START):\r | |
102 | HeaderCommentStage = HEADER_COMMENT_ABSTRACT\r | |
103 | else:\r | |
104 | License += Comment + EndOfLine\r | |
105 | else:\r | |
106 | if HeaderCommentStage == HEADER_COMMENT_ABSTRACT:\r | |
107 | #\r | |
108 | # in case there is no abstract and description\r | |
109 | #\r | |
110 | if not Comment:\r | |
4234283c LG |
111 | HeaderCommentStage = HEADER_COMMENT_DESCRIPTION\r |
112 | elif _IsCopyrightLine(Comment):\r | |
113 | Result, ErrMsg = _ValidateCopyright(Comment)\r | |
114 | ValidateCopyright(Result, ST.WRN_INVALID_COPYRIGHT, FileName, LineNo, ErrMsg)\r | |
115 | Copyright += Comment + EndOfLine\r | |
116 | HeaderCommentStage = HEADER_COMMENT_COPYRIGHT\r | |
f7496d71 | 117 | else:\r |
4234283c LG |
118 | Abstract += Comment + EndOfLine\r |
119 | HeaderCommentStage = HEADER_COMMENT_DESCRIPTION\r | |
120 | elif HeaderCommentStage == HEADER_COMMENT_DESCRIPTION:\r | |
121 | #\r | |
122 | # in case there is no description\r | |
f7496d71 | 123 | #\r |
4234283c LG |
124 | if _IsCopyrightLine(Comment):\r |
125 | Result, ErrMsg = _ValidateCopyright(Comment)\r | |
126 | ValidateCopyright(Result, ST.WRN_INVALID_COPYRIGHT, FileName, LineNo, ErrMsg)\r | |
127 | Copyright += Comment + EndOfLine\r | |
128 | HeaderCommentStage = HEADER_COMMENT_COPYRIGHT\r | |
129 | else:\r | |
f7496d71 | 130 | Description += Comment + EndOfLine\r |
4234283c LG |
131 | elif HeaderCommentStage == HEADER_COMMENT_COPYRIGHT:\r |
132 | if _IsCopyrightLine(Comment):\r | |
133 | Result, ErrMsg = _ValidateCopyright(Comment)\r | |
134 | ValidateCopyright(Result, ST.WRN_INVALID_COPYRIGHT, FileName, LineNo, ErrMsg)\r | |
135 | Copyright += Comment + EndOfLine\r | |
136 | else:\r | |
137 | #\r | |
138 | # Contents after copyright line are license, those non-copyright lines in between\r | |
f7496d71 | 139 | # copyright line will be discarded\r |
4234283c LG |
140 | #\r |
141 | if LineNo > Last:\r | |
142 | if License:\r | |
143 | License += EndOfLine\r | |
144 | License += Comment + EndOfLine\r | |
f7496d71 | 145 | HeaderCommentStage = HEADER_COMMENT_LICENSE\r |
4234283c LG |
146 | else:\r |
147 | if not Comment and not License:\r | |
148 | continue\r | |
149 | License += Comment + EndOfLine\r | |
f7496d71 | 150 | \r |
4234283c LG |
151 | return Abstract.strip(), Description.strip(), Copyright.strip(), License.strip()\r |
152 | \r | |
153 | ## _IsCopyrightLine\r | |
f7496d71 LG |
154 | # check whether current line is copyright line, the criteria is whether there is case insensitive keyword "Copyright"\r |
155 | # followed by zero or more white space characters followed by a "(" character\r | |
4234283c LG |
156 | #\r |
157 | # @param LineContent: the line need to be checked\r | |
158 | # @return: True if current line is copyright line, False else\r | |
159 | #\r | |
160 | def _IsCopyrightLine (LineContent):\r | |
161 | LineContent = LineContent.upper()\r | |
162 | Result = False\r | |
f7496d71 | 163 | \r |
4234283c LG |
164 | ReIsCopyrightRe = re.compile(r"""(^|\s)COPYRIGHT *\(""", re.DOTALL)\r |
165 | if ReIsCopyrightRe.search(LineContent):\r | |
166 | Result = True\r | |
421ccda3 | 167 | \r |
4234283c LG |
168 | return Result\r |
169 | \r | |
170 | ## ParseGenericComment\r | |
171 | #\r | |
f7496d71 | 172 | # @param GenericComment: Generic comment list, element of\r |
4234283c LG |
173 | # (CommentLine, LineNum)\r |
174 | # @param ContainerFile: Input value for filename of Dec file\r | |
f7496d71 | 175 | #\r |
4234283c LG |
176 | def ParseGenericComment (GenericComment, ContainerFile=None, SkipTag=None):\r |
177 | if ContainerFile:\r | |
178 | pass\r | |
f7496d71 LG |
179 | HelpTxt = None\r |
180 | HelpStr = ''\r | |
181 | \r | |
4234283c LG |
182 | for Item in GenericComment:\r |
183 | CommentLine = Item[0]\r | |
184 | Comment = CleanString2(CommentLine)[1]\r | |
185 | if SkipTag is not None and Comment.startswith(SkipTag):\r | |
186 | Comment = Comment.replace(SkipTag, '', 1)\r | |
187 | HelpStr += Comment + '\n'\r | |
f7496d71 | 188 | \r |
4234283c LG |
189 | if HelpStr:\r |
190 | HelpTxt = TextObject()\r | |
191 | if HelpStr.endswith('\n') and not HelpStr.endswith('\n\n') and HelpStr != '\n':\r | |
192 | HelpStr = HelpStr[:-1]\r | |
193 | HelpTxt.SetString(HelpStr)\r | |
194 | \r | |
195 | return HelpTxt\r | |
196 | \r | |
421ccda3 HC |
197 | ## ParsePcdErrorCode\r |
198 | #\r | |
f7496d71 | 199 | # @param Value: original ErrorCode value\r |
421ccda3 | 200 | # @param ContainerFile: Input value for filename of Dec file\r |
f7496d71 LG |
201 | # @param LineNum: Line Num\r |
202 | #\r | |
203 | def ParsePcdErrorCode (Value = None, ContainerFile = None, LineNum = None):\r | |
204 | try:\r | |
421ccda3 HC |
205 | if Value.strip().startswith((TAB_HEX_START, TAB_CAPHEX_START)):\r |
206 | Base = 16\r | |
207 | else:\r | |
208 | Base = 10\r | |
174a9d3c | 209 | ErrorCode = int(Value, Base)\r |
421ccda3 | 210 | if ErrorCode > PCD_ERR_CODE_MAX_SIZE or ErrorCode < 0:\r |
f7496d71 | 211 | Logger.Error('Parser',\r |
421ccda3 HC |
212 | FORMAT_NOT_SUPPORTED,\r |
213 | "The format %s of ErrorCode is not valid, should be UNIT32 type or long type" % Value,\r | |
f7496d71 | 214 | File = ContainerFile,\r |
421ccda3 | 215 | Line = LineNum)\r |
174a9d3c ZF |
216 | ErrorCode = '0x%x' % ErrorCode\r |
217 | return ErrorCode\r | |
5b0671c1 | 218 | except ValueError as XStr:\r |
421ccda3 HC |
219 | if XStr:\r |
220 | pass\r | |
f7496d71 | 221 | Logger.Error('Parser',\r |
421ccda3 HC |
222 | FORMAT_NOT_SUPPORTED,\r |
223 | "The format %s of ErrorCode is not valid, should be UNIT32 type or long type" % Value,\r | |
f7496d71 | 224 | File = ContainerFile,\r |
421ccda3 | 225 | Line = LineNum)\r |
f7496d71 | 226 | \r |
4234283c LG |
227 | ## ParseDecPcdGenericComment\r |
228 | #\r | |
f7496d71 | 229 | # @param GenericComment: Generic comment list, element of (CommentLine,\r |
4234283c LG |
230 | # LineNum)\r |
231 | # @param ContainerFile: Input value for filename of Dec file\r | |
f7496d71 LG |
232 | #\r |
233 | def ParseDecPcdGenericComment (GenericComment, ContainerFile, TokenSpaceGuidCName, CName, MacroReplaceDict):\r | |
234 | HelpStr = ''\r | |
421ccda3 | 235 | PromptStr = ''\r |
4234283c | 236 | PcdErr = None\r |
421ccda3 HC |
237 | PcdErrList = []\r |
238 | ValidValueNum = 0\r | |
239 | ValidRangeNum = 0\r | |
240 | ExpressionNum = 0\r | |
f7496d71 | 241 | \r |
4234283c LG |
242 | for (CommentLine, LineNum) in GenericComment:\r |
243 | Comment = CleanString2(CommentLine)[1]\r | |
421ccda3 HC |
244 | #\r |
245 | # To replace Macro\r | |
246 | #\r | |
247 | MACRO_PATTERN = '[\t\s]*\$\([A-Z][_A-Z0-9]*\)'\r | |
248 | MatchedStrs = re.findall(MACRO_PATTERN, Comment)\r | |
249 | for MatchedStr in MatchedStrs:\r | |
250 | if MatchedStr:\r | |
251 | Macro = MatchedStr.strip().lstrip('$(').rstrip(')').strip()\r | |
252 | if Macro in MacroReplaceDict:\r | |
f7496d71 | 253 | Comment = Comment.replace(MatchedStr, MacroReplaceDict[Macro])\r |
421ccda3 HC |
254 | if Comment.startswith(TAB_PCD_VALIDRANGE):\r |
255 | if ValidValueNum > 0 or ExpressionNum > 0:\r | |
f7496d71 | 256 | Logger.Error('Parser',\r |
4234283c LG |
257 | FORMAT_NOT_SUPPORTED,\r |
258 | ST.WRN_MULTI_PCD_RANGES,\r | |
f7496d71 | 259 | File = ContainerFile,\r |
4234283c | 260 | Line = LineNum)\r |
421ccda3 | 261 | else:\r |
4234283c | 262 | PcdErr = PcdErrorObject()\r |
421ccda3 HC |
263 | PcdErr.SetTokenSpaceGuidCName(TokenSpaceGuidCName)\r |
264 | PcdErr.SetCName(CName)\r | |
265 | PcdErr.SetFileLine(Comment)\r | |
266 | PcdErr.SetLineNum(LineNum)\r | |
267 | ValidRangeNum += 1\r | |
268 | ValidRange = Comment.replace(TAB_PCD_VALIDRANGE, "", 1).strip()\r | |
269 | Valid, Cause = _CheckRangeExpression(ValidRange)\r | |
270 | if Valid:\r | |
271 | ValueList = ValidRange.split(TAB_VALUE_SPLIT)\r | |
272 | if len(ValueList) > 1:\r | |
273 | PcdErr.SetValidValueRange((TAB_VALUE_SPLIT.join(ValueList[1:])).strip())\r | |
274 | PcdErr.SetErrorNumber(ParsePcdErrorCode(ValueList[0], ContainerFile, LineNum))\r | |
275 | else:\r | |
276 | PcdErr.SetValidValueRange(ValidRange)\r | |
277 | PcdErrList.append(PcdErr)\r | |
278 | else:\r | |
279 | Logger.Error("Parser",\r | |
280 | FORMAT_NOT_SUPPORTED,\r | |
f7496d71 LG |
281 | Cause,\r |
282 | ContainerFile,\r | |
421ccda3 HC |
283 | LineNum)\r |
284 | elif Comment.startswith(TAB_PCD_VALIDLIST):\r | |
285 | if ValidRangeNum > 0 or ExpressionNum > 0:\r | |
f7496d71 | 286 | Logger.Error('Parser',\r |
4234283c LG |
287 | FORMAT_NOT_SUPPORTED,\r |
288 | ST.WRN_MULTI_PCD_RANGES,\r | |
f7496d71 | 289 | File = ContainerFile,\r |
4234283c | 290 | Line = LineNum)\r |
421ccda3 | 291 | elif ValidValueNum > 0:\r |
f7496d71 | 292 | Logger.Error('Parser',\r |
421ccda3 HC |
293 | FORMAT_NOT_SUPPORTED,\r |
294 | ST.WRN_MULTI_PCD_VALIDVALUE,\r | |
f7496d71 | 295 | File = ContainerFile,\r |
421ccda3 HC |
296 | Line = LineNum)\r |
297 | else:\r | |
298 | PcdErr = PcdErrorObject()\r | |
299 | PcdErr.SetTokenSpaceGuidCName(TokenSpaceGuidCName)\r | |
300 | PcdErr.SetCName(CName)\r | |
301 | PcdErr.SetFileLine(Comment)\r | |
302 | PcdErr.SetLineNum(LineNum)\r | |
303 | ValidValueNum += 1\r | |
304 | ValidValueExpr = Comment.replace(TAB_PCD_VALIDLIST, "", 1).strip()\r | |
305 | Valid, Cause = _CheckListExpression(ValidValueExpr)\r | |
306 | if Valid:\r | |
307 | ValidValue = Comment.replace(TAB_PCD_VALIDLIST, "", 1).replace(TAB_COMMA_SPLIT, TAB_SPACE_SPLIT)\r | |
308 | ValueList = ValidValue.split(TAB_VALUE_SPLIT)\r | |
309 | if len(ValueList) > 1:\r | |
310 | PcdErr.SetValidValue((TAB_VALUE_SPLIT.join(ValueList[1:])).strip())\r | |
311 | PcdErr.SetErrorNumber(ParsePcdErrorCode(ValueList[0], ContainerFile, LineNum))\r | |
312 | else:\r | |
313 | PcdErr.SetValidValue(ValidValue)\r | |
314 | PcdErrList.append(PcdErr)\r | |
315 | else:\r | |
316 | Logger.Error("Parser",\r | |
317 | FORMAT_NOT_SUPPORTED,\r | |
f7496d71 LG |
318 | Cause,\r |
319 | ContainerFile,\r | |
421ccda3 HC |
320 | LineNum)\r |
321 | elif Comment.startswith(TAB_PCD_EXPRESSION):\r | |
322 | if ValidRangeNum > 0 or ValidValueNum > 0:\r | |
f7496d71 | 323 | Logger.Error('Parser',\r |
4234283c LG |
324 | FORMAT_NOT_SUPPORTED,\r |
325 | ST.WRN_MULTI_PCD_RANGES,\r | |
f7496d71 | 326 | File = ContainerFile,\r |
4234283c | 327 | Line = LineNum)\r |
421ccda3 | 328 | else:\r |
4234283c | 329 | PcdErr = PcdErrorObject()\r |
421ccda3 HC |
330 | PcdErr.SetTokenSpaceGuidCName(TokenSpaceGuidCName)\r |
331 | PcdErr.SetCName(CName)\r | |
332 | PcdErr.SetFileLine(Comment)\r | |
333 | PcdErr.SetLineNum(LineNum)\r | |
334 | ExpressionNum += 1\r | |
335 | Expression = Comment.replace(TAB_PCD_EXPRESSION, "", 1).strip()\r | |
336 | Valid, Cause = _CheckExpression(Expression)\r | |
337 | if Valid:\r | |
338 | ValueList = Expression.split(TAB_VALUE_SPLIT)\r | |
339 | if len(ValueList) > 1:\r | |
340 | PcdErr.SetExpression((TAB_VALUE_SPLIT.join(ValueList[1:])).strip())\r | |
341 | PcdErr.SetErrorNumber(ParsePcdErrorCode(ValueList[0], ContainerFile, LineNum))\r | |
342 | else:\r | |
343 | PcdErr.SetExpression(Expression)\r | |
344 | PcdErrList.append(PcdErr)\r | |
f7496d71 | 345 | else:\r |
421ccda3 HC |
346 | Logger.Error("Parser",\r |
347 | FORMAT_NOT_SUPPORTED,\r | |
f7496d71 LG |
348 | Cause,\r |
349 | ContainerFile,\r | |
350 | LineNum)\r | |
421ccda3 HC |
351 | elif Comment.startswith(TAB_PCD_PROMPT):\r |
352 | if PromptStr:\r | |
f7496d71 | 353 | Logger.Error('Parser',\r |
421ccda3 HC |
354 | FORMAT_NOT_SUPPORTED,\r |
355 | ST.WRN_MULTI_PCD_PROMPT,\r | |
f7496d71 | 356 | File = ContainerFile,\r |
421ccda3 HC |
357 | Line = LineNum)\r |
358 | PromptStr = Comment.replace(TAB_PCD_PROMPT, "", 1).strip()\r | |
4234283c | 359 | else:\r |
421ccda3 HC |
360 | if Comment:\r |
361 | HelpStr += Comment + '\n'\r | |
f7496d71 | 362 | \r |
4234283c LG |
363 | #\r |
364 | # remove the last EOL if the comment is of format 'FOO\n'\r | |
365 | #\r | |
366 | if HelpStr.endswith('\n'):\r | |
367 | if HelpStr != '\n' and not HelpStr.endswith('\n\n'):\r | |
368 | HelpStr = HelpStr[:-1]\r | |
369 | \r | |
421ccda3 | 370 | return HelpStr, PcdErrList, PromptStr\r |
4234283c LG |
371 | \r |
372 | ## ParseDecPcdTailComment\r | |
373 | #\r | |
374 | # @param TailCommentList: Tail comment list of Pcd, item of format (Comment, LineNum)\r | |
375 | # @param ContainerFile: Input value for filename of Dec file\r | |
376 | # @retVal SupModuleList: The supported module type list detected\r | |
377 | # @retVal HelpStr: The generic help text string detected\r | |
378 | #\r | |
379 | def ParseDecPcdTailComment (TailCommentList, ContainerFile):\r | |
380 | assert(len(TailCommentList) == 1)\r | |
381 | TailComment = TailCommentList[0][0]\r | |
382 | LineNum = TailCommentList[0][1]\r | |
383 | \r | |
384 | Comment = TailComment.lstrip(" #")\r | |
f7496d71 | 385 | \r |
4234283c | 386 | ReFindFirstWordRe = re.compile(r"""^([^ #]*)""", re.DOTALL)\r |
f7496d71 | 387 | \r |
4234283c LG |
388 | #\r |
389 | # get first word and compare with SUP_MODULE_LIST\r | |
390 | #\r | |
391 | MatchObject = ReFindFirstWordRe.match(Comment)\r | |
392 | if not (MatchObject and MatchObject.group(1) in SUP_MODULE_LIST):\r | |
393 | return None, Comment\r | |
394 | \r | |
395 | #\r | |
396 | # parse line, it must have supported module type specified\r | |
397 | #\r | |
398 | if Comment.find(TAB_COMMENT_SPLIT) == -1:\r | |
f7496d71 | 399 | Comment += TAB_COMMENT_SPLIT\r |
4234283c LG |
400 | SupMode, HelpStr = GetSplitValueList(Comment, TAB_COMMENT_SPLIT, 1)\r |
401 | SupModuleList = []\r | |
402 | for Mod in GetSplitValueList(SupMode, TAB_SPACE_SPLIT):\r | |
403 | if not Mod:\r | |
404 | continue\r | |
405 | elif Mod not in SUP_MODULE_LIST:\r | |
406 | Logger.Error("UPT",\r | |
407 | FORMAT_INVALID,\r | |
f7496d71 LG |
408 | ST.WRN_INVALID_MODULE_TYPE%Mod,\r |
409 | ContainerFile,\r | |
4234283c LG |
410 | LineNum)\r |
411 | else:\r | |
412 | SupModuleList.append(Mod)\r | |
413 | \r | |
414 | return SupModuleList, HelpStr\r | |
415 | \r | |
421ccda3 HC |
416 | ## _CheckListExpression\r |
417 | #\r | |
f7496d71 | 418 | # @param Expression: Pcd value list expression\r |
421ccda3 HC |
419 | #\r |
420 | def _CheckListExpression(Expression):\r | |
421 | ListExpr = ''\r | |
422 | if TAB_VALUE_SPLIT in Expression:\r | |
f7496d71 | 423 | ListExpr = Expression[Expression.find(TAB_VALUE_SPLIT)+1:]\r |
421ccda3 HC |
424 | else:\r |
425 | ListExpr = Expression\r | |
f7496d71 | 426 | \r |
421ccda3 HC |
427 | return IsValidListExpr(ListExpr)\r |
428 | \r | |
429 | ## _CheckExpreesion\r | |
430 | #\r | |
431 | # @param Expression: Pcd value expression\r | |
432 | #\r | |
433 | def _CheckExpression(Expression):\r | |
434 | Expr = ''\r | |
435 | if TAB_VALUE_SPLIT in Expression:\r | |
436 | Expr = Expression[Expression.find(TAB_VALUE_SPLIT)+1:]\r | |
437 | else:\r | |
438 | Expr = Expression\r | |
439 | return IsValidLogicalExpr(Expr, True)\r | |
4234283c LG |
440 | \r |
441 | ## _CheckRangeExpression\r | |
442 | #\r | |
443 | # @param Expression: Pcd range expression\r | |
f7496d71 | 444 | #\r |
4234283c | 445 | def _CheckRangeExpression(Expression):\r |
421ccda3 HC |
446 | RangeExpr = ''\r |
447 | if TAB_VALUE_SPLIT in Expression:\r | |
448 | RangeExpr = Expression[Expression.find(TAB_VALUE_SPLIT)+1:]\r | |
449 | else:\r | |
450 | RangeExpr = Expression\r | |
f7496d71 | 451 | \r |
421ccda3 | 452 | return IsValidRangeExpr(RangeExpr)\r |
4234283c LG |
453 | \r |
454 | ## ValidateCopyright\r | |
455 | #\r | |
456 | #\r | |
457 | #\r | |
458 | def ValidateCopyright(Result, ErrType, FileName, LineNo, ErrMsg):\r | |
459 | if not Result:\r | |
f7496d71 | 460 | Logger.Warn("\nUPT", ErrType, FileName, LineNo, ErrMsg)\r |
4234283c LG |
461 | \r |
462 | ## _ValidateCopyright\r | |
463 | #\r | |
464 | # @param Line: Line that contains copyright information, # stripped\r | |
f7496d71 | 465 | #\r |
4234283c LG |
466 | # @retval Result: True if line is conformed to Spec format, False else\r |
467 | # @retval ErrMsg: the detailed error description\r | |
f7496d71 | 468 | #\r |
4234283c LG |
469 | def _ValidateCopyright(Line):\r |
470 | if Line:\r | |
471 | pass\r | |
472 | Result = True\r | |
473 | ErrMsg = ''\r | |
f7496d71 | 474 | \r |
4234283c LG |
475 | return Result, ErrMsg\r |
476 | \r | |
477 | def GenerateTokenList (Comment):\r | |
478 | #\r | |
479 | # Tokenize Comment using '#' and ' ' as token seperators\r | |
480 | #\r | |
f7496d71 | 481 | RelplacedComment = None\r |
4234283c LG |
482 | while Comment != RelplacedComment:\r |
483 | RelplacedComment = Comment\r | |
484 | Comment = Comment.replace('##', '#').replace(' ', ' ').replace(' ', '#').strip('# ')\r | |
485 | return Comment.split('#')\r | |
486 | \r | |
487 | \r | |
488 | #\r | |
489 | # Comment - Comment to parse\r | |
490 | # TypeTokens - A dictionary of type token synonyms\r | |
491 | # RemoveTokens - A list of tokens to remove from help text\r | |
492 | # ParseVariable - True for parsing [Guids]. Otherwise False\r | |
493 | #\r | |
494 | def ParseComment (Comment, UsageTokens, TypeTokens, RemoveTokens, ParseVariable):\r | |
495 | #\r | |
496 | # Initialize return values\r | |
497 | #\r | |
498 | Usage = None\r | |
499 | Type = None\r | |
500 | String = None\r | |
f7496d71 | 501 | \r |
4234283c | 502 | Comment = Comment[0]\r |
f7496d71 LG |
503 | \r |
504 | NumTokens = 2\r | |
4234283c | 505 | if ParseVariable:\r |
f7496d71 LG |
506 | #\r |
507 | # Remove white space around first instance of ':' from Comment if 'Variable'\r | |
4234283c LG |
508 | # is in front of ':' and Variable is the 1st or 2nd token in Comment.\r |
509 | #\r | |
f7496d71 | 510 | List = Comment.split(':', 1)\r |
4234283c LG |
511 | if len(List) > 1:\r |
512 | SubList = GenerateTokenList (List[0].strip())\r | |
513 | if len(SubList) in [1, 2] and SubList[-1] == 'Variable':\r | |
f7496d71 | 514 | if List[1].strip().find('L"') == 0:\r |
4234283c | 515 | Comment = List[0].strip() + ':' + List[1].strip()\r |
f7496d71 LG |
516 | \r |
517 | #\r | |
4234283c | 518 | # Remove first instance of L"<VariableName> from Comment and put into String\r |
f7496d71 | 519 | # if and only if L"<VariableName>" is the 1st token, the 2nd token. Or\r |
4234283c LG |
520 | # L"<VariableName>" is the third token immediately following 'Variable:'.\r |
521 | #\r | |
522 | End = -1\r | |
523 | Start = Comment.find('Variable:L"')\r | |
524 | if Start >= 0:\r | |
525 | String = Comment[Start + 9:]\r | |
526 | End = String[2:].find('"')\r | |
527 | else:\r | |
528 | Start = Comment.find('L"')\r | |
529 | if Start >= 0:\r | |
530 | String = Comment[Start:]\r | |
531 | End = String[2:].find('"')\r | |
532 | if End >= 0:\r | |
533 | SubList = GenerateTokenList (Comment[:Start])\r | |
f7496d71 | 534 | if len(SubList) < 2:\r |
4234283c LG |
535 | Comment = Comment[:Start] + String[End + 3:]\r |
536 | String = String[:End + 3]\r | |
537 | Type = 'Variable'\r | |
f7496d71 LG |
538 | NumTokens = 1\r |
539 | \r | |
4234283c | 540 | #\r |
f7496d71 | 541 | # Initialze HelpText to Comment.\r |
4234283c | 542 | # Content will be remove from HelpText as matching tokens are found\r |
f7496d71 | 543 | #\r |
4234283c | 544 | HelpText = Comment\r |
f7496d71 | 545 | \r |
4234283c LG |
546 | #\r |
547 | # Tokenize Comment using '#' and ' ' as token seperators\r | |
548 | #\r | |
549 | List = GenerateTokenList (Comment)\r | |
f7496d71 | 550 | \r |
4234283c | 551 | #\r |
f7496d71 | 552 | # Search first two tokens for Usage and Type and remove any matching tokens\r |
4234283c LG |
553 | # from HelpText\r |
554 | #\r | |
555 | for Token in List[0:NumTokens]:\r | |
4231a819 | 556 | if Usage is None and Token in UsageTokens:\r |
4234283c LG |
557 | Usage = UsageTokens[Token]\r |
558 | HelpText = HelpText.replace(Token, '')\r | |
4231a819 | 559 | if Usage is not None or not ParseVariable:\r |
4234283c | 560 | for Token in List[0:NumTokens]:\r |
4231a819 | 561 | if Type is None and Token in TypeTokens:\r |
4234283c LG |
562 | Type = TypeTokens[Token]\r |
563 | HelpText = HelpText.replace(Token, '')\r | |
f7496d71 | 564 | if Usage is not None:\r |
4234283c LG |
565 | for Token in List[0:NumTokens]:\r |
566 | if Token in RemoveTokens:\r | |
567 | HelpText = HelpText.replace(Token, '')\r | |
f7496d71 | 568 | \r |
4234283c LG |
569 | #\r |
570 | # If no Usage token is present and set Usage to UNDEFINED\r | |
f7496d71 | 571 | #\r |
4231a819 | 572 | if Usage is None:\r |
4234283c | 573 | Usage = 'UNDEFINED'\r |
f7496d71 | 574 | \r |
4234283c LG |
575 | #\r |
576 | # If no Type token is present and set Type to UNDEFINED\r | |
f7496d71 | 577 | #\r |
4231a819 | 578 | if Type is None:\r |
4234283c | 579 | Type = 'UNDEFINED'\r |
f7496d71 | 580 | \r |
4234283c LG |
581 | #\r |
582 | # If Type is not 'Variable:', then set String to None\r | |
f7496d71 | 583 | #\r |
4234283c | 584 | if Type != 'Variable':\r |
f7496d71 LG |
585 | String = None\r |
586 | \r | |
4234283c LG |
587 | #\r |
588 | # Strip ' ' and '#' from the beginning of HelpText\r | |
f7496d71 | 589 | # If HelpText is an empty string after all parsing is\r |
4234283c | 590 | # complete then set HelpText to None\r |
f7496d71 | 591 | #\r |
4234283c LG |
592 | HelpText = HelpText.lstrip('# ')\r |
593 | if HelpText == '':\r | |
594 | HelpText = None\r | |
f7496d71 | 595 | \r |
4234283c LG |
596 | #\r |
597 | # Return parsing results\r | |
f7496d71 LG |
598 | #\r |
599 | return Usage, Type, String, HelpText\r |